Subversion Repositories eFlore/Applications.del

Rev

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

package org.tela_botanica.del.client.composants.pagination;

import org.tela_botanica.del.client.navigation.evenement.BusEvenementiel;
import org.tela_botanica.del.client.navigation.evenement.pagination.EvenementChangementPage;
import org.tela_botanica.del.client.navigation.evenement.pagination.EvenementChangementPas;
import org.tela_botanica.del.client.navigation.evenement.pagination.GestionnaireEvenementChangementPage;
import org.tela_botanica.del.client.navigation.evenement.pagination.GestionnaireEvenementChangementPas;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;

/**
 * @author gregoire Pagination GENERIQUE qui permet d'afficher un nombre donné
 *         d'éléments (pas) La méthode changerPage est abstraite et doit être
 *         définie lors de l'instanciation de la classe pagination pour
 *         permettre d'afficher la suite des éléments La méthode
 *         actualiserPasCache est abstraite car le pas est différent en fonction
 *         de la page où l'on se trouve
 * */
public abstract class PaginationPresenteur {

        public interface Vue extends IsWidget {
                public HasClickHandlers getBoutonSuivant();
                public HasClickHandlers getBoutonPrecedent();
                public HasClickHandlers getBoutonPremierePage();
                public HasClickHandlers getBoutonDernierePage();
                public void masquerBoutonPrecedent();
                public void afficherBoutonPrecedent();
                public void masquerBoutonSuivant();
                public void afficherBoutonSuivant();
                public boolean boutonPrecedentEstAffiche();
                public boolean boutonSuivantEstAffiche();
                public HasChangeHandlers getSelecteurPas();
                public int getPasSelectionne();
                public void afficherPas(int pas);
                public void mettreNbTotalPages(int nbPages);
                public void mettreNbTotalResultats(int nbResultats);
                public HasChangeHandlers getSaisiePageCourante();
                public int getPageSaisie();
                public void setPageCourante(int pageCourante);
        }

        private Vue vue;
        private int nbPage = 1;
        //private int nbPage = 1;
        private int pageCourante = 1;
        private int nbElementsTotal = 0;
        private int pas = 10;

        private String groupePagination = null;

        /**
         * Constructeur de l'application
         * 
         * @param nbElementsTotal
         *            : le nombre total des éléments à paginer
         * @param pas
         *            : le nombre d'éléments à afficher par page
         * */
        public PaginationPresenteur(Vue vue, int nbElementsTotal, int pas, int pageCourante) {
                this.nbElementsTotal = nbElementsTotal;
                this.vue = vue;
                this.pas = pas;
                this.pageCourante = pageCourante;
                vue.setPageCourante(pageCourante);
                this.nbPage = calculerNbPage();
        }

        /**
         * Methode go du modèle MVP
         * 
         * @param container
         *            : la vue ou éxécuter l'affichage
         */
        public void go(HasWidgets container) {
                container.add(vue.asWidget());
                gererEvenements();
                actualiserPas();
                actualiserAffichageBoutons();
                vue.mettreNbTotalPages(nbPage);
                vue.mettreNbTotalResultats(nbElementsTotal);
        }

        /**
         * Gérer les évènements sur les boutons statiques (précédent, suivant et
         * selecteur pas)
         * */
        protected void gererEvenements() {
                
                vue.getSaisiePageCourante().addChangeHandler(new ChangeHandler() {
                        @Override
                        public void onChange(ChangeEvent event) {
                                int pageSaisie;
                                try {
                                        pageSaisie = vue.getPageSaisie();
                                        if (pageSaisie < 0) {
                                                pageSaisie = 1;
                                        } else if (pageSaisie > nbPage){
                                                pageSaisie = nbPage;
                                        }
                                } catch (NumberFormatException e) {
                                        pageSaisie = pageCourante;
                                }
                                pageCourante = pageSaisie;
                                chargerElements(pas * (pageCourante - 1), pas * (pageCourante));
                                vue.setPageCourante(pageCourante);
                                actualiserAffichageBoutons();
                        }
                });
                
                vue.getSelecteurPas().addChangeHandler(new ChangeHandler() {
                        @Override
                        public void onChange(ChangeEvent event) {
                                int pasSelectionne;
                                try {
                                        pasSelectionne = vue.getPasSelectionne();
                                        if (pasSelectionne < 0) {
                                                pasSelectionne = 1;
                                        } else if (pasSelectionne > 100){
                                                pasSelectionne = 100;
                                        }
                                } catch (NumberFormatException e) {
                                        pasSelectionne = pas;
                                }
                                 
                                changerPas(pasSelectionne);
                        }
                });

                vue.getBoutonPrecedent().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                allerALaPagePrecedente();
                        }
                });

                vue.getBoutonSuivant().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                allerALapageSuivante();
                        }
                });

                vue.getBoutonPremierePage().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                allerALaPremierePage();
                        }
                });

                vue.getBoutonDernierePage().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                allerAlaDernierePage();
                        }
                });

                BusEvenementiel.getInstance().addHandler(EvenementChangementPage.TYPE, new GestionnaireEvenementChangementPage() {

                        @Override
                        public void onChangementPage(EvenementChangementPage event) {
                                if (event.getGroupePagination() == groupePagination) {
                                        pageCourante = event.getPageAAfficher();
                                        vue.setPageCourante(pageCourante);
                                        actualiserAffichageBoutons();
                                        vue.mettreNbTotalPages(nbPage);
                                        vue.mettreNbTotalResultats(nbElementsTotal);
                                }
                        }
                });

                BusEvenementiel.getInstance().addHandler(EvenementChangementPas.TYPE, new GestionnaireEvenementChangementPas() {

                        @Override
                        public void onChangementPas(EvenementChangementPas event) {
                                if (event.getGroupePagination() == groupePagination) {
                                        // modifie le pas et les liens en fonction
                                        pas = event.getPas();
                                        actualiserPas();
                                }
                        }
                });
        }

        private void gererDecalagePageCourante(int ancienPas, int nouveauPas) {
                if (ancienPas != nouveauPas) {
                        double rapportPas = (double) ancienPas / (double) nouveauPas;
                        pageCourante = (int) (Math.ceil((double) pageCourante * (double) rapportPas));
                }
        }

        public void actualiserPas() {
                actualiserPasCache(pas);
                vue.afficherPas(pas);
        }

                public int getPageCourante() {
                return this.pageCourante;
        }

        public int getPas() {
                return this.pas;
        }

        public void setPageCourante(int pageCourante) {
                this.pageCourante = pageCourante;
        }

        public void changerPas(int nouveauPas) {

                // TODO corriger bug qui ne charge pas la bonne page ds certains cas
                // gererDecalagePageCourante(pas, nouveauPas);
                // pas = nouveauPas;
                // chargerElements((pageCourante - 1)*pas, pageCourante*pas);
                pas = nouveauPas;
                this.nbPage = calculerNbPage();
                chargerElements(0, pas);
                BusEvenementiel.getInstance().fireEvent(new EvenementChangementPas(nouveauPas, groupePagination));
                BusEvenementiel.getInstance().fireEvent(new EvenementChangementPage(1, groupePagination));
        }

        public void allerALaPagePrecedente() {
                if (pageCourante > 1) {
                        int pageAAfficher = pageCourante - 1;
                        pageCourante = pageAAfficher;
                        chargerElements(pas * (pageAAfficher - 1), pas * (pageAAfficher));
                        BusEvenementiel.getInstance().fireEvent(new EvenementChangementPage(pageAAfficher, groupePagination));
                }

        }

        public void allerALapageSuivante() {
                if (pageCourante < nbPage) {
                        int pageAAfficher = pageCourante + 1;
                        pageCourante = pageAAfficher;
                        chargerElements(pas * (pageAAfficher - 1), pas * (pageAAfficher));
                        BusEvenementiel.getInstance().fireEvent(new EvenementChangementPage(pageAAfficher, groupePagination));
                }
        }

        public void allerALaPremierePage() {
                int pageAAfficher = 1;
                pageCourante = pageAAfficher;
                chargerElements(0, pas);
                BusEvenementiel.getInstance().fireEvent(new EvenementChangementPage(pageAAfficher, groupePagination));
        }

        public void allerAlaDernierePage() {
                int pageAAfficher = nbPage;
                pageCourante = pageAAfficher;
                chargerElements(pas * (pageAAfficher - 1), pas * (pageAAfficher));
                BusEvenementiel.getInstance().fireEvent(new EvenementChangementPage(pageAAfficher, groupePagination));
        }

        /** calcule le nombre de page en fonction du pas */
        private int calculerNbPage() {
                Double nombrePages = Math.ceil((double) nbElementsTotal / (double) pas);
                return nombrePages.intValue();
        }

        public void setNbPages(int nbPages) {
                this.nbPage = nbPages;
        }

        public int getNbPages() {
                return nbPage;
        }

        public Vue getVue() {
                return vue;
        }

        public abstract void chargerElements(int debut, int fin);

        public abstract void actualiserPasCache(int pas);

        public void setPas(int pas) {
                this.pas = pas;
        }

        public void setGroupePagination(String groupePagination) {
                this.groupePagination = groupePagination;
        }

        public String getGroupePagination() {
                return groupePagination;
        }

        public void actualiserAffichageBoutons() {
                if (nbPage == 1) {
                        vue.masquerBoutonPrecedent();
                        vue.masquerBoutonSuivant();
                } else if (pageCourante == 1) {
                        vue.masquerBoutonPrecedent();
                        vue.afficherBoutonSuivant();
                } else {
                        vue.afficherBoutonPrecedent();
                        if (pageCourante == nbPage) {
                                vue.masquerBoutonSuivant();
                        }
                } 
        }
}