Subversion Repositories eFlore/Applications.coel

Rev

Rev 1896 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.tela_botanica.client.vues.publication;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.tela_botanica.client.ComposantClass;
import org.tela_botanica.client.Mediateur;
import org.tela_botanica.client.composants.ChampComboBoxRechercheTempsReelPaginable;
import org.tela_botanica.client.composants.GrillePaginable;
import org.tela_botanica.client.composants.InfoLogger;
import org.tela_botanica.client.composants.pagination.ProxyPersonnes;
import org.tela_botanica.client.composants.pagination.ProxyPersonnesAPublication;
import org.tela_botanica.client.composants.pagination.ProxyStructures;
import org.tela_botanica.client.images.Images;
import org.tela_botanica.client.interfaces.Rafraichissable;
import org.tela_botanica.client.modeles.Information;
import org.tela_botanica.client.modeles.MenuApplicationId;
import org.tela_botanica.client.modeles.aDonnee;
import org.tela_botanica.client.modeles.personne.Personne;
import org.tela_botanica.client.modeles.publication.Publication;
import org.tela_botanica.client.modeles.publication.PublicationAPersonne;
import org.tela_botanica.client.modeles.publication.PublicationAPersonneListe;
import org.tela_botanica.client.modeles.structure.Structure;
import org.tela_botanica.client.synchronisation.Sequenceur;
import org.tela_botanica.client.util.Debug;
import org.tela_botanica.client.util.Log;
import org.tela_botanica.client.util.Pattern;
import org.tela_botanica.client.util.UtilArray;
import org.tela_botanica.client.util.UtilString;
import org.tela_botanica.client.vues.FenetreForm;
import org.tela_botanica.client.vues.Formulaire;
import org.tela_botanica.client.vues.FormulaireBarreValidation;
import org.tela_botanica.client.vues.personne.PersonneForm;

import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.data.LoadEvent;
import com.extjs.gxt.ui.client.data.Loader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelType;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.Validator;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;


public class PublicationForm extends Formulaire implements Rafraichissable {
        
          //-------------//
         //  ATTRIBUTS  //
        //-------------//
        
        /** Publication **/
        // on se sert d'un objet Publication lorsque l'on est en mode MODIFIER
        private Publication publication;
        // on se sert de l'identifiant d'une publication lorsque l'on est en mode AJOUTER
        private String publicationId = null;
        
        /** Auteurs **/
        private PublicationAPersonneListe auteursInitialListe = null;
        private PublicationAPersonneListe auteursAjoutes = null;
        private PublicationAPersonneListe auteursSupprimes = null;
        private PublicationAPersonneListe auteursModifies = null;
        
        private ContentPanel auteursFieldset = null;
        
        private FieldSet generalitesFieldset = null;
        private TextField<String> titreChp = null;
        private TextField<String> collectionChp = null;
        private TextField<String> uriChp = null;
        
        private FieldSet editionFieldset = null;
        private ChampComboBoxRechercheTempsReelPaginable editeurCombobox = null;
        private TextField<String> datePublicationChp = null;
        private TextField<String> tomeChp = null;
        private TextField<String> fasciculeChp = null;
        private TextField<String> pagesChp = null;
        
        private LayoutContainer zoneHaut, zoneBas;
        
        private ToolBar barreOutils = null;
        private GrillePaginable<ModelData> grilleAuteurs;
        private ChampComboBoxRechercheTempsReelPaginable personnesSaisiesComboBox = null;
        private Button personnesBoutonSupprimer = null;
        private Button personnesBoutonModifier = null;
        private Button boutonAuteurUp = null;
        private Button boutonAuteurDown = null;
        
        private FenetreForm fenetreFormulaire = null;
        private Sequenceur sequenceur;
        
        private String modeDeCreation = null;
        boolean changeOrderMarker = false;
        
        private Label infosAuteurFmt = null;
        private ContentPanel infosAuteursNonPresentsPanel = null;
        
        
        //+----------------------------------------------------------------------------------------------------------------+
        //    Constructeurs     
        
        public PublicationForm(Mediateur mediateurCourrant, String publicationId) {
                initialiserPublicationForm(mediateurCourrant, publicationId);
        }

        public PublicationForm(Mediateur mediateurCourrant, String publicationId, Rafraichissable vueARafraichirApresValidation) {
                vueExterneARafraichirApresValidation = vueARafraichirApresValidation;
                initialiserPublicationForm(mediateurCourrant, publicationId);
        }

        
        //+----------------------------------------------------------------------------------------------------------------+
        //    Initialisation
        
        private void initialiserPublicationForm(Mediateur mediateurCourrant, String publicationId) {
                sequenceur = new Sequenceur();
                publication = new Publication();
                publication.setId(publicationId);
                this.publicationId = publicationId;
                auteursInitialListe = new PublicationAPersonneListe();
                initialiserAuteurs();   // Crée les listes d'auteurs ajoutés et supprimés
                // Si 'publicationId' est vide alors on est en mode "AJOUTER", sinon on est en mode "MODIFIER" 
                modeDeCreation = (UtilString.isEmpty(publicationId) ? Formulaire.MODE_AJOUTER : Formulaire.MODE_MODIFIER);
                initialiserFormulaire(mediateurCourrant, modeDeCreation, MenuApplicationId.PUBLICATION);
                panneauFormulaire.setLayout(new RowLayout());
                panneauFormulaire.setStyleAttribute("padding", "0");
                panneauFormulaire.setHeight(600);
                
                zoneHaut = new LayoutContainer(new FitLayout());
                zoneBas = new LayoutContainer(new FlowLayout());
                panneauFormulaire.add(zoneHaut, new RowData(0.99, 0.45));
                panneauFormulaire.add(zoneBas, new RowData(0.99, 0.55));
                panneauFormulaire.setScrollMode(Scroll.AUTO);
                genererTitreFormulaire();
                
                creerZoneAuteurs();
                zoneHaut.add(auteursFieldset);
                
                creerZoneGeneralites();
                zoneBas.add(generalitesFieldset);
                
                creerZoneEdition();
                zoneBas.add(editionFieldset);
                
                if (modeDeCreation.equals(Formulaire.MODE_MODIFIER)) {
                        mediateurCourrant.selectionnerPublication(this, publicationId, sequenceur);
                        sequenceur.enfilerRafraichissement(this, new Information("chargement_modifier_ok"));
                }
        }

        private void initialiserAuteurs() {
                auteursAjoutes = new PublicationAPersonneListe();
                auteursSupprimes = new PublicationAPersonneListe();
                auteursModifies = new PublicationAPersonneListe();
        }
        
        //+----------------------------------------------------------------------------------------------------------------+
        //    User Interface
        
        private ToolBar creerBarreOutilsGrille() {
                ToolBar barreOutils = new ToolBar();  
                
                creerComboBoxPersonnesSaisies();
                barreOutils.add(personnesSaisiesComboBox);
                
                personnesSaisiesComboBox.getCombo().setEmptyText("Rechercher et sélectionner une personne existante dans la base");
                
                barreOutils.add(new Text(" ou "));
                
                Button ajouterBouton = creerBoutonAjouter();
                barreOutils.add(ajouterBouton);
                
                barreOutils.add(new SeparatorToolItem());
                
                personnesBoutonModifier = creerBoutonModifier();
                barreOutils.add(personnesBoutonModifier);
                
                barreOutils.add(new SeparatorToolItem());
                
                personnesBoutonSupprimer = creerBoutonSupprimer();
                barreOutils.add(personnesBoutonSupprimer);              
                
                barreOutils.add(new SeparatorToolItem());
                
                Button rafraichirBouton = creerBoutonRafraichir();
                barreOutils.add(rafraichirBouton);
                
                barreOutils.add(new SeparatorToolItem());
                
                barreOutils.add(new Text(i18nC.deplacerAuteur()));
                boutonAuteurUp = creerBoutonAuteurUp();
                barreOutils.add(boutonAuteurUp);
                boutonAuteurDown = creerBoutonAuteurDown();
                barreOutils.add(boutonAuteurDown);
                
                return barreOutils;
        }
        
        public void actualiserEtatBoutonsBarreOutils() {
                // Activation des boutons si la grille contient un élément
                if (grilleAuteurs.getStore().getCount() > 0) {  
                        personnesBoutonSupprimer.enable();
                        personnesBoutonModifier.enable();
                }
                // Désactivation des boutons si la grille ne contient plus d'élément
                if (grilleAuteurs.getStore().getCount() == 0) {  
                        personnesBoutonSupprimer.disable();
                        personnesBoutonModifier.disable();
                }
        }
        
        private Button creerBoutonAuteurUp() {
                Button bouton = new Button();
                bouton.setIcon(Images.ICONES.arrowUp());
                bouton.setEnabled(false);
                bouton.addSelectionListener(new SelectionListener<ButtonEvent>() {
                        public void componentSelected(ButtonEvent ce) {  
                                if (grilleAuteurs.getGrille().getSelectionModel().getSelectedItem() != null) {
                                        mettreAJourOrdreAuteur(-1);
                                }
                        }  
                });
                return bouton;
        }
        
        private Button creerBoutonAuteurDown() {
                Button bouton = new Button();
                bouton.setIcon(Images.ICONES.arrowDown());
                bouton.setEnabled(false);
                bouton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
                        public void componentSelected(ButtonEvent ce) {  
                                if (grilleAuteurs.getSelectionModel().getSelectedItem() != null) {
                                        mettreAJourOrdreAuteur(+1);
                                }
                        }  
                });
                return bouton;
        }
        
        private void formaterOrdreAuteurs() {
                List<ModelData> auteurs = grilleAuteurs.getStore().getModels();
                Iterator<ModelData> itAuteurs = auteurs.iterator();
                while (itAuteurs.hasNext())     {
                        ModelData selection = itAuteurs.next();
                        PublicationAPersonne pap = new PublicationAPersonne(selection, false);
                        
                        String ordre = String.valueOf(grilleAuteurs.getStore().indexOf(selection) + 1);
                        if (pap.getOrdreAuteurs() != ordre) {
                                selection.set("_ordre_", ordre);
                                grilleAuteurs.getStore().update(selection);
                                pap.setOrdreAuteurs(ordre);
                                auteursModifies.put(pap.getId(), pap);
                        }
                } 
        }
        
        private void mettreAJourOrdreAuteur(int monterOuDescendre) {
                ModelData publiAPersonneSelectionnee = grilleAuteurs.getSelectionModel().getSelectedItem();
                int index = grilleAuteurs.getStore().indexOf(publiAPersonneSelectionnee);
                int nouvelIndex = index + monterOuDescendre;
                
                if (verifierOrdreAuteur(nouvelIndex)) {
                        // le marqueur suivant est obligatoire sinon les évènements liés au magasin se
                        // déclenchent et posent problème
                        changeOrderMarker = true;
                        
                        int indexAPermuter = index + monterOuDescendre;
                        ModelData publiAPersonneSwitch = grilleAuteurs.getStore().getAt(indexAPermuter);
                        String ordreAPermuter = String.valueOf((indexAPermuter + 1) - monterOuDescendre);
                        publiAPersonneSwitch.set("_ordre_", ordreAPermuter);
                        grilleAuteurs.getStore().update(publiAPersonneSwitch);
                        PublicationAPersonne papSwitch = new PublicationAPersonne(publiAPersonneSwitch, false);
                        papSwitch.setOrdreAuteurs(ordreAPermuter);
                        auteursModifies.put(papSwitch.getId(), papSwitch);

                        grilleAuteurs.getStore().remove(publiAPersonneSelectionnee);
                        String nouvelOrdre = String.valueOf((index + 1) + monterOuDescendre);
                        publiAPersonneSelectionnee.set("_ordre_", nouvelOrdre);
                        grilleAuteurs.getStore().insert(publiAPersonneSelectionnee, nouvelIndex);
                        PublicationAPersonne papSelectionnee = new PublicationAPersonne(publiAPersonneSelectionnee, false);
                        papSelectionnee.setOrdreAuteurs(nouvelOrdre);
                        auteursModifies.put(papSelectionnee.getId(), papSelectionnee);
                        changeOrderMarker = false;
                        
                        grilleAuteurs.getSelectionModel().select(nouvelIndex, false);
                }
        }
        
        private boolean verifierOrdreAuteur(int nouvelIndex) {
                int nbrElement = grilleAuteurs.getStore().getCount();
                boolean ok = true;
                if (nouvelIndex < 0 || nouvelIndex >= nbrElement) {
                        ok = false;
                }
                return ok;
        }
        
        private void activerBoutonsOrdreAuteur() {
                ModelData papSelectionnee = grilleAuteurs.getGrille().getSelectionModel().getSelectedItem();
                int index = grilleAuteurs.getStore().indexOf(papSelectionnee);
                
                if (index >= 1) {
                        boutonAuteurUp.setEnabled(true);
                } else {
                        boutonAuteurUp.setEnabled(false);
                }
                
                if ((index+1) < grilleAuteurs.getStore().getCount()) {
                        boutonAuteurDown.setEnabled(true);
                } else {
                        boutonAuteurDown.setEnabled(false);
                }
        }
        
        private Button creerBoutonAjouter() {
                Button bouton = new Button(i18nC.ajouter());
                bouton.setIcon(Images.ICONES.vcardAjouter());
                bouton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
                        public void componentSelected(ButtonEvent ce) {  
                                fenetreFormulaire = creerFenetreModaleAvecFormulairePersonne(Formulaire.MODE_AJOUTER);
                                fenetreFormulaire.show();
                        }  
                });
                return bouton;
        }
        
        private Button creerBoutonModifier() {
                Button bouton = new Button(i18nC.modifier());
                bouton.setIcon(Images.ICONES.vcardModifier());
                bouton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
                        public void componentSelected(ButtonEvent ce) {  
                                Personne personneSaisieSelectionnee = new PublicationAPersonne(grilleAuteurs.getSelectionModel().getSelectedItem(), false).getPersonne();
                                
                                if (personneSaisieSelectionnee == null) {
                                        InfoLogger.display(i18nC.informationTitreGenerique(), i18nC.selectionnerPublication());
                                } else {
                                        fenetreFormulaire = creerFenetreModaleAvecFormulairePersonne(Formulaire.MODE_MODIFIER);
                                        fenetreFormulaire.show();
                                }
                        }  
                });
                return bouton;
        }
        
        private FenetreForm creerFenetreModaleAvecFormulairePersonne(String mode) {
                String personneId = null;
                if (mode.equals(Formulaire.MODE_MODIFIER)) {
                        Personne personneSaisieSelectionnee = new PublicationAPersonne(grilleAuteurs.getSelectionModel().getSelectedItem(), false).getPersonne();
                        personneId = personneSaisieSelectionnee.getId();
                }
                
                final FenetreForm fenetre = new FenetreForm("");
                final PersonneForm formulaire = creerFormulairePersonne(fenetre, personneId);
                fenetre.add(formulaire);
                return fenetre;
        }
        
        private PersonneForm creerFormulairePersonne(final FenetreForm fenetre, final String personneId) {
                PersonneForm formulairePersonne = new PersonneForm(mediateur, personneId, this);
                FormPanel panneauFormulaire = formulairePersonne.getFormulaire();
                fenetre.setHeadingHtml(panneauFormulaire.getHeadingHtml());
                panneauFormulaire.setHeaderVisible(false);
                panneauFormulaire.setTopComponent(null);
                
                // FIXME : avec GXT-2.1.0 la redéfinition du bottom component ne marche plus. Nous le cachons et en créeons un dans la fenêtre.
                panneauFormulaire.getBottomComponent().hide();
                SelectionListener<ButtonEvent> ecouteur = creerEcouteurValidationFormulairePersonne(fenetre, formulairePersonne);
                final ButtonBar barreValidation = new FormulaireBarreValidation(ecouteur);
                fenetre.setBottomComponent(barreValidation);
                
                return formulairePersonne;
        }
        
        private SelectionListener<ButtonEvent> creerEcouteurValidationFormulairePersonne(final FenetreForm fenetre, final PersonneForm formulaire) {
                SelectionListener<ButtonEvent> ecouteur = new SelectionListener<ButtonEvent>() {
                        public void componentSelected(ButtonEvent ce) {
                                String code = ((Button) ce.getComponent()).getData("code");
                                if (code.equals(FormulaireBarreValidation.CODE_BOUTON_VALIDER)) {
                                        if (formulaire.soumettreFormulaire()) {
                                                fenetre.hide();
                                        }
                                } else if (code.equals(FormulaireBarreValidation.CODE_BOUTON_APPLIQUER)) {
                                        formulaire.soumettreFormulaire();
                                } else if (code.equals(FormulaireBarreValidation.CODE_BOUTON_ANNULER)) {
                                        fenetre.hide();
                                }
                        }
                };
                
                return ecouteur;
        }
        
        private Button creerBoutonSupprimer() {
                Button bouton = new Button(i18nC.supprimer());
                bouton.setIcon(Images.ICONES.vcardSupprimer());
                bouton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
                        public void componentSelected(ButtonEvent ce) {
                                supprimerDansGrille();
                        }   
                });
                return bouton;
        }
        
        private Button creerBoutonRafraichir() {
                Button bouton = new Button(i18nC.rafraichir());
                bouton.setIcon(Images.ICONES.rafraichir());
                bouton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
                        public void componentSelected(ButtonEvent ce) {
                                actualiserGrille();
                        }   
                });
                return bouton;
        }
        
        private void actualiserGrille() {
                if (mode.equals(Formulaire.MODE_MODIFIER)) {
                        // FIXME : c'est la merde
                        grilleAuteurs.reload();
                } else {
                        grilleAuteurs.getStore().removeAll();
                        layout();
                }
        }
        
        private void creerComboBoxPersonnesSaisies() {
                ModelType modelTypePersonnes = new ModelType();
                modelTypePersonnes.setRoot("personnes");
                modelTypePersonnes.setTotalName("nbElements");
                modelTypePersonnes.addField("cp_fmt_nom_complet");
                modelTypePersonnes.addField("cp_nom");
                modelTypePersonnes.addField("cp_prenom");
                modelTypePersonnes.addField("cp_id_personne");
                modelTypePersonnes.addField("cp_code_postal");
                modelTypePersonnes.addField("cp_ville");
                modelTypePersonnes.addField("cp_truk_courriel");
                
                String displayNamePersonnes = "cp_fmt_nom_complet";
                ProxyPersonnes<ModelData> proxyPersonnes = new ProxyPersonnes<ModelData>(null);
                
                personnesSaisiesComboBox = new ChampComboBoxRechercheTempsReelPaginable(proxyPersonnes, modelTypePersonnes, displayNamePersonnes);
                
                personnesSaisiesComboBox.getCombo().addListener(Events.Select, new Listener<BaseEvent>() {
                        public void handleEvent(BaseEvent be) {         
                                if (personnesSaisiesComboBox.getValeur() instanceof ModelData) {
                                        // N'ajouter l'auteur que s'il n'est pas déjà présent dans la grille et dans les valeurs initiales
                                        Personne personneSaisieSelectionnee = new Personne(personnesSaisiesComboBox.getValeur());
                                        Log.debug("Récupération info combo :"+personneSaisieSelectionnee.toString());
                                        PublicationAPersonne pap = new PublicationAPersonne(aDonnee.GARDER_PREFIXE);                                    
                                        pap.setPersonne(personneSaisieSelectionnee, aDonnee.INTEGRER_PROPRIETES);
                                        pap.setOrdreAuteurs(String.valueOf(grilleAuteurs.getStore().getCount()+1));
                                        if (modeDeCreation != Formulaire.MODE_AJOUTER) {
                                                pap.setPublicationLiee(publication);
                                                pap.setIdPublication(publicationId);
                                        }
                                        pap.setIdRole(PublicationAPersonne.ROLE_AUTEUR);
                                        Log.debug("Récupération info combo pap id :"+pap.getId());
                                        
                                        if (ajouterDansGrille(pap)) {
                                                personnesSaisiesComboBox.getCombo().setValue(null);
                                        }
                                }
                        }
                });
        }
        
        private boolean ajouterDansGrille(PublicationAPersonne pap) {
                return ajouterDansGrille(pap, grilleAuteurs.getStore().getCount());
        }
        
        private boolean ajouterDansGrille(PublicationAPersonne pap, int index) {
                boolean ok = false;
                if (pap != null) {
                        Log.debug("Début ajout dans grille :"+pap.toString());
                        if (grilleAuteurs.getStore().contains((ModelData) pap)) {
                                InfoLogger.display("Information", "La personne choisie existe déjà dans la liste d'auteurs.");
                        } else {
                                // 1) si elle ne fait pas partie des initiaux, ajouter à la liste à ajouter
                                if (!auteursInitialListe.containsValue(pap))    {
                                        auteursAjoutes.put(pap.getId(), pap);
                                        Log.debug("Ajout dans grille -> auteur '"+pap.getId()+"' a été ajouté à la liste des ajoutés (il ne fait pas parti de la liste initiale).");
                                }
                                
                                // L'enlever de la liste à supprimer
                                if (auteursSupprimes.containsValue(pap))        {
                                        auteursSupprimes.remove(pap);
                                        Log.debug("Ajout dans grille -> auteur '"+pap.getId()+"' a été retiré de la liste des supprimés.");
                                }
                                
                                // 2) Ajouter a la grille
                                grilleAuteurs.getStore().insert((ModelData) pap, index);
                                grilleAuteurs.getSelectionModel().select(index, false);
                                ok = true;
                        }
                }
                return ok;
        }
        
        private void supprimerDansGrille() {
                List<ModelData> listeDonneesSelectionnees = grilleAuteurs.getSelectionModel().getSelectedItems();
                for (ModelData donneeSelectionnee : listeDonneesSelectionnees) {
                        supprimerAuteurDansGrille(donneeSelectionnee);
                }
        }
        
        private void supprimerAuteurDansGrille(ModelData donneeSelectionnee) {
                PublicationAPersonne personneSelectionnee = new PublicationAPersonne(donneeSelectionnee, aDonnee.GARDER_PREFIXE);
                Log.debug("Début supprimer auteur dans grille : "+personneSelectionnee.toString());
                if (personneSelectionnee.getId() == null) {
                        InfoLogger.display(i18nC.informationTitreGenerique(), i18nC.selectionnerAuteur());
                } else {
                        // 1) Ajouter a la liste des personne à supprimer uniquement si est présente dans la liste initiale
                        if (auteursInitialListe.containsKey(personneSelectionnee.getId())) {
                                auteursSupprimes.put(personneSelectionnee.getId(), personneSelectionnee);
                                Log.debug("Ajout Personne à supprimer : "+auteursSupprimes.toString());
                        }
                        
                        if (auteursAjoutes.containsKey(personneSelectionnee.getId()))   {
                                auteursAjoutes.remove(personneSelectionnee.getId());
                        }
                        
                        if (auteursModifies.containsKey(personneSelectionnee.getId()))  {
                                auteursModifies.remove(personneSelectionnee.getId());
                        }
                        
                        // 2) Supprimer la personne de la liste
                        Log.debug("Personne trouvée : "+grilleAuteurs.getStore().findModel(donneeSelectionnee).toString());
                        grilleAuteurs.getStore().remove(donneeSelectionnee);
                        formaterOrdreAuteurs();
                }
        }
        
        private GrillePaginable<ModelData> creerGrilleAuteurs() {
                // ModelType
                ModelType modelTypePersonnesAPublication = new ModelType();
                modelTypePersonnesAPublication.setRoot("publicationsAPersonne");
                modelTypePersonnesAPublication.setTotalName("nbElements");
                modelTypePersonnesAPublication.addField("cpuap_id_personne");
                modelTypePersonnesAPublication.addField("cpuap_id_publication");
                modelTypePersonnesAPublication.addField("cpuap_id_role");
                modelTypePersonnesAPublication.addField("cpuap_ordre");
                modelTypePersonnesAPublication.addField("cp_id_personne");
                modelTypePersonnesAPublication.addField("cp_fmt_nom_complet");
                modelTypePersonnesAPublication.addField("cp_nom");
                modelTypePersonnesAPublication.addField("cp_prenom");
                modelTypePersonnesAPublication.addField("cp_id_personne");
                modelTypePersonnesAPublication.addField("cp_code_postal");
                modelTypePersonnesAPublication.addField("cp_ville");
                modelTypePersonnesAPublication.addField("cp_truk_courriel");
                
                // Proxy
                ProxyPersonnesAPublication<ModelData> proxyPersonnesAPublication = new ProxyPersonnesAPublication<ModelData>(null, publicationId);              

                // Colonnes
                List<ColumnConfig> colonnes = new ArrayList<ColumnConfig>();
                ColumnConfig columnOrdre = new ColumnConfig("_ordre_", i18nC.ordre(), 15);
                colonnes.add(columnOrdre);
                colonnes.add(new ColumnConfig("cp_fmt_nom_complet", i18nC.personneNomComplet(), 150));
                colonnes.add(new ColumnConfig("cp_code_postal", i18nC.personneCodePostal(), 150));
                colonnes.add(new ColumnConfig("cp_ville", i18nC.personneVille(), 75));
                colonnes.add(new ColumnConfig("cp_truk_courriel", i18nC.personneCourriel(), 75));               
                
                // Champs de traitement
                HashMap<String, String> virtualFields = new HashMap<String, String>();
                virtualFields.put("_ordre_", "cpuap_ordre");
                
                // Modele de selection
                GridSelectionModel<ModelData> modeleDeSelection = new GridSelectionModel<ModelData>();
                modeleDeSelection.addListener(Events.SelectionChange, new SelectionChangedListener<ModelData>() {
                        public void selectionChanged(SelectionChangedEvent<ModelData> se) {
                                activerBoutonsOrdreAuteur();
                        }
                });
                
                ColumnModel modeleDeColonnes = new ColumnModel(colonnes);
                
                // Grille
                // ATTENTION : le constructure de cette grille est à vérifier!
                final GrillePaginable<ModelData> grilleAuteurs = new GrillePaginable<ModelData>(modelTypePersonnesAPublication, virtualFields, proxyPersonnesAPublication, colonnes, modeleDeColonnes);         
                grilleAuteurs.getGrille().setHeight("100%");
                grilleAuteurs.getGrille().setBorders(true);
                grilleAuteurs.getGrille().setSelectionModel(modeleDeSelection);
                grilleAuteurs.getGrille().getView().setForceFit(true);
                grilleAuteurs.getGrille().setAutoExpandColumn("fmt_nom_complet");
                grilleAuteurs.getGrille().setStripeRows(true);
                grilleAuteurs.getGrille().setTrackMouseOver(true);
                
                grilleAuteurs.getStore().getLoader().addListener(Loader.Load, new Listener<LoadEvent>() {
                        public void handleEvent(LoadEvent be) {                                 
                                List<ModelData> auteurs = grilleAuteurs.getStore().getModels();
                                Iterator<ModelData> itAuteurs = auteurs.iterator();
                                while (itAuteurs.hasNext())     {
                                        ModelData selection = itAuteurs.next();
                                        PublicationAPersonne pap = new PublicationAPersonne(selection, aDonnee.GARDER_PREFIXE);
                                        auteursInitialListe.put(pap.getId(), pap);
                                        Log.debug("PublicationAPersonne ajoutée à la liste initiale avec l'id :"+pap.getId()+pap.toString()+selection.getProperties().toString());
                                }
                                controlerCoherenceAuteurs();
                                //zefgzf
                                Log.debug("Initialisation liste auteur :"+auteursInitialListe.size());
                        }  
                });
                
                // Rajouter des écouteurs
                grilleAuteurs.getStore().addListener(Store.Add, new Listener<StoreEvent<ModelData>>() {
                        public void handleEvent(StoreEvent<ModelData> ce) {
                                if (!changeOrderMarker) {                                       
                                        actualiserEtatBoutonsBarreOutils();
                                }
                        }
                });
                grilleAuteurs.getStore().addListener(Store.Remove, new Listener<StoreEvent<ModelData>>() {
                        public void handleEvent(StoreEvent<ModelData> ce) {
                                if (!changeOrderMarker) {                                       
                                        actualiserEtatBoutonsBarreOutils();
                                        Log.debug("Dans listener remove de grilleAuteur");
                                }
                        }
                });
                grilleAuteurs.getStore().addListener(Store.Update, new Listener<StoreEvent<ModelData>>() {
                        public void handleEvent(StoreEvent<ModelData> ce) {
                                
                        }
                });             
                
                return grilleAuteurs;
        }
        
        private void genererTitreFormulaire() {
                String titre = i18nC.publicationTitreFormAjout();
                if (mode.equals(Formulaire.MODE_MODIFIER)) {
                         titre = i18nC.publicationTitreFormModif();
                         if (publication != null) {
                                 titre += " - "+i18nC.id()+": "+publication.getId()+" - "+publication.getTitre();
                         }
                }
                panneauFormulaire.setHeadingHtml(titre);
        }

        
        private void creerZoneAuteurs() {
                auteursFieldset = new ContentPanel();
                auteursFieldset.setLayout(new FitLayout());
                auteursFieldset.setHeadingHtml("Auteurs");
                
                creerChampsAuteur();
        }
        
        private void creerChampsAuteur() {
                auteursFieldset.removeAll();
                barreOutils = creerBarreOutilsGrille();
                auteursFieldset.setTopComponent(barreOutils);
                grilleAuteurs = creerGrilleAuteurs();
                auteursFieldset.add(grilleAuteurs);                             
                
                auteursFieldset.layout();
        }
        
        private void creerZoneGeneralites() {
                FormLayout layout = new FormLayout();
                layout.setLabelWidth(200);
                
                // Fieldset Infos Générales
                generalitesFieldset = new FieldSet();
                generalitesFieldset.setHeadingHtml("Informations générales");
                generalitesFieldset.setCollapsible(true);
                generalitesFieldset.setLayout(layout);
                
                infosAuteursNonPresentsPanel = new ContentPanel();
                Label LabelAuteurFmt = new Label("Auteurs de la publication : ");
                LabelAuteurFmt.setId("label-auteurs-non-presents");
                infosAuteurFmt = new Label(publication.getAuteur());
                Label avertissementAuteurs = new Label("Attention, Certains auteurs apparaissent ci-dessous mais pas dans la grille des auteurs. "+
                                                                                                "Ceci signifie que la publication a été importée sans que tous les auteurs aient été créés auparavant.<br />"+
                                                                                                "Si vous souhaitez modifier cette publication, nous vous invitons à y associer correctement les auteurs grâce à la grille ci-dessus.<br />");
                
                infosAuteursNonPresentsPanel.setHeaderVisible(false);
                infosAuteursNonPresentsPanel.setId("infos-auteurs-non-presents");
                
                infosAuteursNonPresentsPanel.add(avertissementAuteurs);
                infosAuteursNonPresentsPanel.add(LabelAuteurFmt);
                infosAuteursNonPresentsPanel.add(infosAuteurFmt);
                infosAuteursNonPresentsPanel.setVisible(false);
                
                generalitesFieldset.add(infosAuteursNonPresentsPanel);
                
                
                titreChp = new TextField<String>();
                titreChp.setName("cpu");
                titreChp.setFieldLabel("Titre de l'article ou de l'ouvrage");
                titreChp.addStyleName(ComposantClass.OBLIGATOIRE);
                titreChp.addListener(Events.Valid, creerEcouteurChampObligatoire());
                generalitesFieldset.add(titreChp, new FormData(450, 0));
                
                collectionChp = new TextField<String>();
                collectionChp.setFieldLabel("Intitulé de la revue ou de la collection");
                generalitesFieldset.add(collectionChp, new FormData(450, 0));
                
                uriChp = new TextField<String>();
                uriChp.setFieldLabel("URL de la publication");
                generalitesFieldset.add(uriChp, new FormData(450, 0));
        }
        
        private void creerZoneEdition() {
                FormLayout layout = new FormLayout();
                layout.setLabelWidth(200);

                // Fieldset Edition
                editionFieldset = new FieldSet();
                editionFieldset.setHeadingHtml("Édition");
                editionFieldset.setCollapsible(true);
                editionFieldset.setLayout(layout);
                
                /*****************************************************/
                /**                     Champ 'Editeur de la publication'               **/
                /*****************************************************/         
                ModelType modelTypeStructures = new ModelType();
                modelTypeStructures.setRoot("structures");
                modelTypeStructures.setTotalName("nbElements");
                modelTypeStructures.addField("cs_nom");
                modelTypeStructures.addField("cs_id_structure");
                
                String displayNameStructures = "cs_nom";
                ProxyStructures<ModelData> proxyStructures = new ProxyStructures<ModelData>(null);
                
                editeurCombobox = new ChampComboBoxRechercheTempsReelPaginable(proxyStructures, modelTypeStructures, displayNameStructures);
                editeurCombobox.setWidth(200, 600);
                editeurCombobox.getCombo().setTabIndex(tabIndex++);
                editeurCombobox.getCombo().setEmptyText("Sélectionner un éditeur...");
                editeurCombobox.getCombo().setFieldLabel("Éditeur de la publication");
                editeurCombobox.getCombo().setEditable(true);
                editionFieldset.add(editeurCombobox, new FormData(600, 0));
                
                /*********************************************/
                /**                     Champ 'Date de publication'             **/
                /*********************************************/                 
                datePublicationChp = new TextField<String>();
                datePublicationChp.setMaxLength(9);
                datePublicationChp.setMinLength(4);
                datePublicationChp.setFieldLabel("Année de publication");
                datePublicationChp.addStyleName(ComposantClass.OBLIGATOIRE);
                datePublicationChp.addListener(Events.Valid, creerEcouteurChampObligatoire());
                editionFieldset.add(datePublicationChp, new FormData(80, 0));
                
                /*********************************/
                /**                     Champ 'Tome'            **/
                /*********************************/     
                tomeChp = new TextField<String>();
                tomeChp.setFieldLabel("Série de la revue ou tome");
                editionFieldset.add(tomeChp, new FormData(75, 0));

                /*************************************/
                /**                     Champ 'Fascicule'               **/
                /*************************************/ 
                fasciculeChp = new TextField<String>();
                fasciculeChp.setFieldLabel("Fascicule de la revue");
                editionFieldset.add(fasciculeChp, new FormData(75, 0));

                /*********************************/
                /**                     Champ 'Pages'           **/
                /*********************************/     
                pagesChp = new TextField<String>();
                pagesChp.setFieldLabel("Pages");
                pagesChp.setToolTip("Fomat : NBRE ou NBRE-NBRE. ('NBRE' correspond à une suite de chiffres arabes ou romains ou à un point d'interrogation '?' dans le cas d'une donnée inconnue)");
                editionFieldset.add(pagesChp, new FormData(100, 0));
        }
        
        
        //+----------------------------------------------------------------------------------------------------------------+
        //    Méthodes privées
        
        private void miseAJourAuteursInitialListe() {
                Iterator<String> clesAjoutees = auteursAjoutes.keySet().iterator();
                while (clesAjoutees.hasNext()) {
                        PublicationAPersonne auteurAjoute = auteursAjoutes.get(clesAjoutees.next());
                        auteursInitialListe.put(auteurAjoute.getId(), auteurAjoute);
                }
                
                Iterator<String> clesSupprimees = auteursSupprimes.keySet().iterator();
                while (clesSupprimees.hasNext()) {
                        PublicationAPersonne auteurSupprime = auteursSupprimes.get(clesSupprimees.next());
                        auteursInitialListe.remove(auteurSupprime.getId());
                }
        }
        
        public boolean soumettreFormulaire() {
                boolean formulaireValideOk = verifierFormulaire();
                if (formulaireValideOk) {
                        soumettrePublication();
                }
                
                if(clicBoutonvalidation) {
                        fermerFormulaire();
                }
                
                return formulaireValideOk;
        }

        private void soumettrePublication() {
                Publication publicationCollectee = collecterPublication();
                if (publicationCollectee != null) {
                        // Pour l'enregistrement des publications, on utilise le séquenceur
                        // Il doit attendre le retour de l'enregistrement pour poursuivre
                        sequenceur = new Sequenceur();
                        int seqId = sequenceur.lancerRequeteSynchrone(this);
                        if (mode.equals(Formulaire.MODE_AJOUTER)) {
                                mediateur.ajouterPublication(sequenceur, publicationCollectee, seqId);
                        } else if (mode.equals(Formulaire.MODE_MODIFIER)) {
                                mediateur.modifierPublication(sequenceur, publicationCollectee, seqId);
                        }
                        
                // si l'on est en mode MODIFIER, on soumet les auteurs meme si les informations de la publication
                // restent inchangées car il se peut que les auteurs aient été modifiés
                } else if (mode.equals(Formulaire.MODE_MODIFIER)) {
                        soumettreAuteurs();
                        if(clicBoutonvalidation) {
                                fermerFormulaire();
                        }
                }
        }
        
        private void soumettreAuteurs() {
                //1) Auteurs ajoutés : 
                PublicationAPersonneListe listeAuteursAAjouter = new PublicationAPersonneListe();
                Iterator<String> itAuteur = auteursAjoutes.keySet().iterator();
                while (itAuteur.hasNext())      {                       
                        String cle = itAuteur.next();
                        PublicationAPersonne publiAPersonne = auteursAjoutes.get(cle);
                        Log.debug("Ajouter :"+publiAPersonne.toString());
                        publiAPersonne.setIdPublication(this.publicationId);
                        publiAPersonne.setOrdreAuteurs(publiAPersonne.getOrdreAuteurs());
                        listeAuteursAAjouter.put(cle, publiAPersonne);
                }
                
                // - envoyer au mediateur SSI personnes à ajouter
                if (listeAuteursAAjouter.size() > 0)    {
                        int seqId = sequenceur.lancerRequeteSynchrone(this);
                        mediateur.ajouterPublicationAPersonne(sequenceur, this.publicationId, listeAuteursAAjouter, PublicationAPersonne.ROLE_AUTEUR, seqId);
                }
                
                //2) Auteurs supprimés : 
                PublicationAPersonneListe listeAuteursASupprimer = new PublicationAPersonneListe();
                itAuteur = auteursSupprimes.keySet().iterator();
                while (itAuteur.hasNext())      {
                        String cle = itAuteur.next();
                        PublicationAPersonne publiAPersonne = auteursSupprimes.get(cle);
                        Log.debug("Supprimer :"+publiAPersonne.toString());
                        listeAuteursASupprimer.put(cle, publiAPersonne);
                }
                
                // - Envoyer au médiateur SSI personnes à supprimer
                if (listeAuteursASupprimer.size() > 0) {
                        // Pour une suppression des auteurs, on a pas besoin d'attendre le retour
                        Log.debug("Lancement suppression :"+listeAuteursASupprimer.size());
                        mediateur.supprimerPublicationAPersonne(this, listeAuteursASupprimer);
                }
                
                //3) Auteurs modifiés : 
                PublicationAPersonneListe listeAuteursAModifier = new PublicationAPersonneListe();
                itAuteur = auteursModifies.keySet().iterator();
                while (itAuteur.hasNext())      {
                        String cle = itAuteur.next();
                        PublicationAPersonne publiAPersonne = auteursModifies.get(cle);
                        Log.debug("Modifier :"+publiAPersonne.toString());
                        listeAuteursAModifier.put(cle, publiAPersonne);
                }
                
                // - Envoyer au médiateur SSI personnes à modifier
                if (listeAuteursAModifier.size() > 0) {
                        int seqId = sequenceur.lancerRequeteSynchrone(this);
                        mediateur.modifierPublicationAPersonne(sequenceur, this.publicationId, listeAuteursAModifier, PublicationAPersonne.ROLE_AUTEUR, seqId);
                }
                
                sequenceur.enfilerRafraichissement(this, new Information("auteurs_enregistres"));
        }
        
        private void peuplerFormulaire() {
                titreChp.setValue(publication.getTitre());
                collectionChp.setValue(publication.getCollection());
                uriChp.setValue(publication.getURI());
                datePublicationChp.setValue(publication.getAnneeParution());
                tomeChp.setValue(publication.getIndicationNvt());
                fasciculeChp.setValue(publication.getFascicule());
                pagesChp.setValue(publication.getPages());
                
                // Éditeur est soit une référence à une structure de la base soit une chaine
                if (publication.getEditeur().matches("^[0-9]+$")) {
                        //editeurCombobox.getCombo().setValue(editeurCombobox.getStore().findModel("cs_id_structure", publication.getEditeur()));
                        editeurCombobox.chargerValeurInitiale(publication.getEditeur(), "cs_id_structure");
                } else {
                        editeurCombobox.getCombo().setRawValue(publication.getEditeur());
                }
        }
        
        private Publication collecterPublication() {

                Publication publicationCollectee = (Publication) publication.cloner(new Publication());
                publicationCollectee.setAuteur(construireIntituleAuteur());
                
                String titre = titreChp.getValue();
                publicationCollectee.setTitre(titre);
                
                String collection = collectionChp.getValue();
                publicationCollectee.setCollection(collection);
                
                publicationCollectee.setNomComplet(construireNomComplet());
                
                String uri = uriChp.getValue();
                publicationCollectee.setUri(uri);
                
                String editeur = "";
                if (editeurCombobox.getValeur() != null) {
                        Structure structure = new Structure(editeurCombobox.getValeur());
                        editeur = structure.getId();
                        publicationCollectee.setStructureEditeur(structure);
                } else if (!UtilString.isEmpty(editeurCombobox.getCombo().getRawValue())) {
                        editeur = editeurCombobox.getCombo().getRawValue();
                }
                
                Publication.editeurs.put(editeur, editeurCombobox.getCombo().getRawValue());
                
                publicationCollectee.setEditeur(editeur);
                
                String anneePublication = datePublicationChp.getRawValue();
                publicationCollectee.setAnneeParution(anneePublication);
                
                String tome = tomeChp.getValue();
                publicationCollectee.setIndicationNvt(tome);
                
                String fascicule = fasciculeChp.getValue();
                publicationCollectee.setFascicule(fascicule);
                
                String pages = pagesChp.getValue();
                publicationCollectee.setPages(pages);
                
                Publication publicationARetourner = null;
                if (!publicationCollectee.comparer(publication)) {
                        publicationARetourner = publication = publicationCollectee;
                }
                
                Publication.publisSaisiesModifieesCache.put(publicationId, publicationARetourner);
                return publicationARetourner;
        }
        
        private String construireDate(String valeurDate) {
                
                String dateComplete = "";
                if (!UtilString.isEmpty(valeurDate)){
                        String jour = "00";
                        String mois = "00";
                        String annee = "0000";
                        String messageErreur = null;
                        
                        /**  JJ/MM/AAAA  **/
                        if (valeurDate.matches("\\d{2}/\\d{2}/\\d{4}")) {       
                                
                        }
                                
                        /**  MM/AAAA  **/
                        if (valeurDate.matches("\\d{2}/\\d{4}")) {
                                dateComplete = valeurDate+"-00";                                
                        }
                        
                        /**  AAAA  **/
                        if (valeurDate.matches("\\d{4}")) {
                                dateComplete = valeurDate+"-00-00";     
                        }
                }
                
                return dateComplete;
        }
        
        private String construireIntituleEditeur() {
                String editeur = "";
                if (editeurCombobox.getValeur() != null) {
                        Structure structure = new Structure(editeurCombobox.getValeur());
                        editeur = structure.getNom();
                } else if (!UtilString.isEmpty(editeurCombobox.getCombo().getRawValue())) {
                        editeur = editeurCombobox.getCombo().getRawValue();
                }
                return editeur;
        }
        
        private String construireIntituleAuteur() {
                String intituleAuteur = "";
                
                // rangé par ordre désigné par le champ 'cpuap_ordre' de la table PublicationAPersonne
                grilleAuteurs.getStore().sort("_ordre_", SortDir.ASC);
                List<ModelData> auteurs = grilleAuteurs.getStore().getModels();
                Iterator<ModelData> itAuteurs = auteurs.iterator();
                                
                while (itAuteurs.hasNext())     {
                        Personne personneCourante = new PublicationAPersonne(itAuteurs.next(), false).getPersonne();
                        intituleAuteur += personneCourante.getNom().toUpperCase() + " " + personneCourante.getPrenom();
                        if (itAuteurs.hasNext())        {
                                intituleAuteur+=", ";
                        }
                } 
                return intituleAuteur;
        }
        
        private String construireNomComplet() {
                // Intitulé de la publication complet : fmt_auteur, date_parution(année). titre. Editeur (nom), collection, fascicule, indication_nvt. pages.
                String nomComplet = "";
                String auteurs = construireIntituleAuteur();
                String annee = datePublicationChp.getRawValue();
                String titre = titreChp.getValue();
                String editeur = construireIntituleEditeur();
                
                nomComplet += auteurs+", "+annee+". "+titre+".";
                
                if (!UtilString.isEmpty(editeur)) {
                        nomComplet += " Éditeur "+editeur+".";
                }
                
                if (collectionChp.getValue() != null) {
                        String revue = collectionChp.getValue();
                        nomComplet += ", "+revue;
                }
                
                if (fasciculeChp.getValue() != null) {
                        String fascicule = fasciculeChp.getValue();
                        nomComplet += ", "+fascicule;
                }
                
                if (tomeChp.getValue() != null) {
                        String tomaison = tomeChp.getValue();
                        nomComplet += ", "+tomaison;
                }
                
                if (collectionChp.getValue() != null || fasciculeChp.getValue() != null || tomeChp.getValue() != null) {
                        nomComplet += ".";      
                }
                
                if (pagesChp.getValue() != null) {
                        String pages = pagesChp.getValue();
                        nomComplet += pages+".";
                }
                
                return nomComplet;
        }
        
        public void controlerCoherenceAuteurs() {
                if(doitAfficherAvertissementAuteur()) {
                        infosAuteurFmt.setHtml(publication.getAuteur());
                        infosAuteursNonPresentsPanel.setVisible(true);
                        infosAuteursNonPresentsPanel.setHeight(50);
                } else {
                        infosAuteursNonPresentsPanel.setVisible(false);
                        infosAuteursNonPresentsPanel.setHeight(0);
                }
        }
        
        private boolean doitAfficherAvertissementAuteur() {
                // La construction du fmt nom complet des auteurs étant mal fichue
                // il est plus simple de comparer le nombre d'item une fois les chaines
                // splittées par virgules, ainsi que le nombre d'espace
                String auteurFmtreconstruit = construireIntituleAuteur();
                String[] auteurFmtreconstruitParts = auteurFmtreconstruit.split(",");
                String[] auteurParts = publication.getAuteur().split(",");
                
                String[] auteurFmtreconstruitSpaces = auteurFmtreconstruit.split(" ");
                String[] auteurPartsSpaces = publication.getAuteur().split(" ");
                
                boolean unEstVideEtAutreNon = (auteurFmtreconstruit.trim().isEmpty() != publication.getAuteur().isEmpty());
                
                return (modeDeCreation == MODE_MODIFIER && 
                                (unEstVideEtAutreNon ||
                                auteurFmtreconstruitParts.length != auteurParts.length ||
                                auteurFmtreconstruitSpaces.length != auteurPartsSpaces.length));
        }
        
        //+----------------------------------------------------------------------------------------------------------------+
        //    Méthodes publiques
        
        public boolean verifierFormulaire() {
                boolean valide = true;
                ArrayList<String> messages = new ArrayList<String>();
                
                // Tester si au moins un auteur est présent
                if (grilleAuteurs.getStore().getModels().size() == 0) {
                        messages.add("Veuillez saisir au moins un auteur.");
                }
                
                String titre = titreChp.getValue();
                if (titre == null || titre.equals("")) {
                        messages.add("Veuillez saisir le titre de la publication !");
                }
                
                String uri = uriChp.getValue();
                if (uri != null && ! uri.isEmpty() && ! uri.matches(Pattern.url)) {
                        messages.add("L'URL saisie n'est pas valide !");
                }
                
                String datePublication = datePublicationChp.getRawValue();
                if (datePublication == null || datePublication.equals("")) {
                        messages.add("Veuillez saisir une année de parution !");
                } else {
                        if (!Publication.etreAnneeParutionValide(datePublication)) {
                                messages.add("Le format de l'année saisie est incorrect ! Formats acceptés : AAAA ou AAAA-AAAA");
                        }
                }
                
                String pages = pagesChp.getValue();
                String valeurPage = "(?:[0-9]+|[IVXLCDM]+|\\?)";
                if (pages != null && ! pages.matches("^(?:"+valeurPage+"|"+valeurPage+"-"+valeurPage+")$")) {
                        messages.add("Le format des pages est incorrect !");
                }
                
                if (messages.size() != 0) {
                        String[] tableauDeMessages = {};
                        tableauDeMessages = messages.toArray(tableauDeMessages);
                        MessageBox.alert("Erreurs de saisies", UtilArray.implode(tableauDeMessages, "<br />"), null);
                        valide = false;
                }
                return valide;          
        }
        
        
        //+----------------------------------------------------------------------------------------------------------------+
        //    Accesseurs
        
        //+----------------------------------------------------------------------------------------------------------------+
        //    Rafraichir
        
        public void rafraichir(Object nouvellesDonnees) {
                if (nouvellesDonnees instanceof Publication) {
                        publication = (Publication) nouvellesDonnees;
                } else if (nouvellesDonnees instanceof Information) {
                        rafraichirInformation((Information) nouvellesDonnees);
                } else {
                        GWT.log(Mediateur.i18nM.erreurRafraichir(nouvellesDonnees.getClass(), this.getClass()), null);
                }
        }
        
        private void rafraichirInformation(Information info) {
                
                String type = info.getType();
                if (type.equals("auteurs_enregistres")) {
                        miseAJourAuteursInitialListe();
                        initialiserAuteurs();
                        repandreRafraichissement();
                        controlerFermeture();
                } else if (type.equals("chargement_modifier_ok"))       {
                        Debug.log("Chargement 1");
                        peuplerFormulaire();
                        genererTitreFormulaire();
                }

                if (type.equals("personne_ajoutee")) {
                        if (info.getDonnee(0) != null) {
                                Personne personne = (Personne) info.getDonnee(0);
                                personne = formaterChampPersonnePourGrille(personne);
                                PublicationAPersonne pap = new PublicationAPersonne(personne, false);
                                if (modeDeCreation != Formulaire.MODE_AJOUTER) pap.setPublicationLiee(publication);
                                ajouterDansGrille(pap);
                        }
                } else if (type.equals("personne_modifiee")) {
                        if (info.getDonnee(0) != null) {
                                
                                // créer la nouvelle entrée
                                Personne personne = (Personne) info.getDonnee(0);
                                PublicationAPersonne pap = new PublicationAPersonne();
                                pap.setPersonne(personne);
                                if (modeDeCreation != Formulaire.MODE_AJOUTER) pap.setPublicationLiee(publication);
                                
                                // supprimer l'entrée précédente
                                PublicationAPersonne personneDansGrille = new PublicationAPersonne(grilleAuteurs.getStore().findModel("cp_id_personne", personne.getId()), false);
                                int index = grilleAuteurs.getStore().indexOf(personneDansGrille);
                                grilleAuteurs.getStore().remove(personneDansGrille);
                                if(index != -1) {
                                        // ajouter la nouvelle entrée dans la grille
                                        ajouterDansGrille(pap, index);
                                } else {
                                        ajouterDansGrille(pap);
                                }
                        }
                } else if (info.getType().equals("modif_publication")) {
                        InfoLogger.display("Modification d'une publication", info.toString());
                        soumettreAuteurs();
                } else if (info.getType().equals("ajout_publication")) {
                        if (info.getDonnee(0) != null && info.getDonnee(0) instanceof String && ((String) info.getDonnee(0)).matches("[0-9]+")) {
                                String idPublication = (String) info.getDonnee(0);
                                this.publicationId = idPublication;
                                this.publication.setId(idPublication);                          
                                soumettreAuteurs();
                                InfoLogger.display("Ajout d'une publication", "La publication '"+publicationId+"' a bien été ajoutée");
                        } else {
                                InfoLogger.display("Ajout d'une publication", info.toString());
                        }
                } else if (info.getType().equals("suppression_publication_a_personne")) {
                        InfoLogger.display("Suppression d'auteur", info.getMessages().toString());
                }
        }
        
        private Personne formaterChampPersonnePourGrille(Personne personne) {
                personne.set("cp_id_personne", personne.getId());
                personne.set("cp_fmt_nom_complet", personne.getNomComplet());
                personne.set("cp_fmt_nom_complet", personne.getNomComplet());
                personne.set("cpuap_id_personne", personne.getId());
                personne.set("cp_code_postal", personne.get("code_postal"));
                personne.set("cp_ville", personne.get("ville"));
                personne.set("cp_truk_courriel", personne.getCourriel());
                
                personne.set("cpuap_ordre", grilleAuteurs.getStore().getCount());
                personne.set("cp_nom", personne.getNom());
                personne.set("cp_prenom", personne.getPrenom());
                return personne;
        }
        
        private void repandreRafraichissement() {
                if (vueExterneARafraichirApresValidation != null) {
                        String type = "publication_modifiee";
                        if (mode.equals(Formulaire.MODE_AJOUTER)) {
                                type = "publication_ajoutee";
                        }
                        Information info = new Information(type);
                        info.setDonnee(0, publication);
                        vueExterneARafraichirApresValidation.rafraichir(info);
                }
        }
}