]> SALOME platform Git repositories - tools/eficas.git/blobdiff - Editeur/widgets.py
Salome HOME
PN
[tools/eficas.git] / Editeur / widgets.py
index a08654a4765aa4088e8570fc3eccd97a50b1b676..4f8ab2c5491bd4ff2518fe7a9fe54a64d208dab2 100644 (file)
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #            CONFIGURATION MANAGEMENT OF EDF VERSION
 # ======================================================================
 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
 #          EFICAS
 # ----------------------------------------------------------
 
+import Tkinter
 from Tkinter import *
 import Pmw
 import os,sys,re,string
 import types,fnmatch
+import traceback
 from tkFileDialog import *
 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
 
@@ -35,6 +38,19 @@ from utils import save_in_file
 from centerwindow import centerwindow
 
 from Noyau.N_utils import repr_float
+from Accas import AsException
+
+# Surcharge de la fonction askyesno qui retourne un resultat errone en Python 2.3 avec Tk 8.4
+# et Tkinter.wantobject==1
+import tkMessageBox
+def askyesno(title=None, message=None, **options):
+    "Ask a question; return true if the answer is yes"
+    s = tkMessageBox._show(title, message, tkMessageBox.QUESTION, tkMessageBox.YESNO, **options)
+    if s == tkMessageBox.YES:return 1
+    if s == tkMessageBox.NO:return 0
+    if s:return 1
+    return 0
+
     
 class Fenetre :
     """ Cette classe permet de créer une fenêtre Toplevel dans laquelle
@@ -42,6 +58,7 @@ class Fenetre :
     def __init__(self,appli,titre="",texte=""):
         self.appli=appli
         self.fenetre = Toplevel()
+        self.fenetre.withdraw()
         self.fenetre.configure(width = 800,height=500)
         self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
         self.fenetre.title("Visualisation du "+titre)
@@ -66,13 +83,15 @@ class Fenetre :
         self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
         self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
         # définition des boutons
-        self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
+        self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit,default='active')
         self.but_save = Button(self.frame_boutons,text = "sauver",command = self.save)
         self.but_quit.place(relx=0.4,rely=0.5,anchor='center')
         self.but_save.place(relx=0.6,rely=0.5,anchor='center')
         # affichage du texte
         self.affiche_texte(self.texte)
+       self.zone_texte.config(state=DISABLED)
         centerwindow(self.fenetre)
+        self.fenetre.deiconify()
 
     def page_up(self,event):
         event.widget.yview_scroll(-1, "page")
@@ -114,14 +133,20 @@ class Fenetre :
                                #initialdir = self.appli.CONFIGURATION.rep_user,
                                initialdir = self.appli.CONFIGURATION.initialdir,
                                title="Sauvegarde du "+self.titre)
-        if file != '':
-            if not save_in_file(file,self.texte) :
+        if file :
+            if not save_in_file(file,self.texte,None) :
                 showerror("Sauvegarde impossible",
                        "Impossible de sauvegarder le texte dans le fichier spécifié\n"+
                           "Vérifiez les droits d'écriture")
             else:
                 showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file)
 
+    def destroy(self):
+        try :
+          self.fenetre.destroy()
+       except :
+          pass
+
 class FenetreYesNo(Fenetre):
     def __init__(self,appli,titre="",texte="",yes="Yes",no="No"):
         self.appli=appli
@@ -167,193 +192,290 @@ class FenetreYesNo(Fenetre):
         self.quit()
 
 class FenetreDeSelection(Fenetre):
-    """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.\r
-        Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.\r
-    """\r
-    def __init__(self,panel,item,appli,titre="",texte=""):\r
-        Fenetre.__init__(self,appli,titre=titre,texte=texte)\r
-        self.fenetre.configure(width = 320,height=400)\r
+    """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.
+        Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.
+    """
+    def __init__(self,panel,item,appli,titre="",texte="",cardinal=1):
+        Fenetre.__init__(self,appli,titre=titre,texte=texte)
+       self.frame_boutons.place_forget()
+        self.frame_texte.place_forget()
+        self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.8)
+        self.frame_boutons.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
+
+        self.cardinal=cardinal
+        self.fenetre.configure(width = 320,height=400)
         centerwindow(self.fenetre)
         self.panel = panel
         self.item = item
         self.fenetre.title(titre)
-        self.but_save.configure(text="Ajouter",command=self.traite_selection)\r
-        # séparateur par défaut\r
-        self.separateur = ";"\r
-        # création de la zone de saisie du séparateur\r
-        l_separateurs_autorises = self.get_separateurs_autorises()\r
-        self.choix_sep = Pmw.ComboBox(self.frame_boutons,\r
-                                      label_text = "Séparateur :",\r
-                                      labelpos = 'w',\r
-                                      listheight = 100,\r
-                                      selectioncommand = self.choose_separateur,\r
-                                      scrolledlist_items = l_separateurs_autorises)\r
-        self.choix_sep.component('entry').configure(width=6)\r
-        self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')\r
-        self.choix_sep.selectitem(self.separateur)\r
-        # Replacement\r
-        self.but_quit.place_forget()\r
-        self.but_save.place_forget()\r
-        self.but_save.place(relx=0.6,rely=0.5,anchor='center')\r
-        self.but_quit.place(relx=0.8,rely=0.5,anchor='center')\r
-\r
-    def get_separateurs_autorises(self):\r
-        """\r
-        Retourne la liste des séparateurs autorisés\r
-        """\r
-        return ['espace',';',',']\r
-\r
-    def choose_separateur(self,nom_sep):\r
-        """\r
-        Affecte à self.separateur le caractère séparateur correspondant à nom_sep\r
-        """\r
-        if nom_sep == 'espace' :\r
-            self.separateur = ' '\r
-        else:\r
-            self.separateur = nom_sep\r
-        \r
-    def traite_selection(self):\r
-        """ Cette méthode effectue tous les traitements nécessaires pour vérifier\r
-            et affecter la liste de valeurs à l'objet réprésenté par self.item\r
-        """\r
-        # Récupère la liste des chaines de caractères de la zone sélectionnée\r
-        message,liste = self.recupere_liste()\r
-        if self.test_probleme(message,"Sélectionnez des données") == 0:\r
-            return\r
-        # Vérifie que le nombre de données est dans les limites attendues\r
-        message = self.verif_liste(liste)\r
-        if self.test_probleme(message,"Vérifiez le nombre de données") == 0:\r
-            return\r
-        # Crée une liste de valeurs du type attendu\r
-        message,liste_valeurs = self.creation_liste_valeurs(liste)\r
-        if self.test_probleme(message,"Vérifiez le type des données") == 0:\r
-            return\r
-        # Vérifie que chaque valeur est dans le domaine exigé\r
-        message = self.verif_valeurs(liste_valeurs)\r
-        if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:\r
-            return\r
-        # Ajoute les valeurs dans la liste de valeurs du mot-clé\r
-        self.ajouter_valeurs(liste_valeurs)\r
-        self.appli.affiche_infos("Liste de valeurs acceptée")\r
-\r
-    def test_probleme(self, message, message_eficas):\r
-        """ Cette méthode affiche un message d'erreur si message != ''\r
-            et retourne 0, sinon retourne 1 sans rien afficher.\r
-        """\r
-        if message != "":\r
-            showinfo("Problème",message)\r
-            self.fenetre.tkraise()\r
-            self.appli.affiche_infos(message_eficas)\r
-            return 0\r
-        else:\r
-            return 1\r
-\r
-    def recupere_liste(self):\r
-        """ Cette méthode récupère le texte de la zone sélectionnée, construit et\r
-            retourne une liste avec les chaines qui se trouvent entre les séparateurs.\r
-            S'il n'y a pas de données selectionnées, elle retourne un message d'erreur\r
-            et une liste vide.\r
-        """\r
-        message = ""\r
-        try:\r
-            selection=self.fenetre.selection_get()\r
-        except:\r
-            message = "Pas de donnée sélectionnée"\r
-            return message,None\r
-        # les retours chariots doivent être interprétés comme des séparateurs\r
-        selection = string.replace(selection,'\n',self.separateur)\r
-        # on splitte la sélection suivant le caractère séparateur\r
-        liste_chaines = string.split(selection,self.separateur)\r
-        l_chaines = []\r
-        for chaine in liste_chaines:\r
-            chaine = string.strip(chaine)\r
-            if chaine != '' : l_chaines.append(chaine)\r
-        return message,l_chaines\r
-\r
-    def verif_liste(self, liste):\r
-        """ Cette méthode effectue des tests sur le nombre d'éléments de la liste\r
-            et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur\r
-            correspondant.\r
-        """\r
-        message = ""\r
-        # nombre d'éléments sélectionnés\r
-        nombre_elements = len(liste)\r
-        # nombre d'éléments déja dans la liste du panel\r
-        nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())\r
-        multiplicite = self.item.GetMultiplicite()\r
-        if (nombre_elements % multiplicite) != 0:\r
-            message = "Vous devez sélectionner "+str(multiplicite)+" * n données"\r
-            return message\r
-        nombre_valeurs = nombre_elements / multiplicite\r
-        cardinalite = self.item.GetMinMax()\r
-        if nombre_valeurs < cardinalite[0]:\r
-            message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"\r
-            return message\r
-        if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):\r
-            message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"\r
-            return message\r
-\r
-        return message\r
-\r
-    def creation_liste_valeurs(self, liste):\r
-        """ Cette méthode crée et retourne une liste de valeurs du type attendu\r
-            par le mot-clé. La liste de valeurs est créée à partir de la liste\r
-            de chaines de caractères transmise.\r
-        """\r
-        type_attendu = self.item.GetType()[0]\r
-        if type_attendu == 'R':\r
-            return self.convertir(liste, f_conversion= float)\r
-        elif type_attendu == 'I':\r
-            return self.convertir(liste, f_conversion= int)\r
-        elif type_attendu == 'TXM':\r
-            return self.convertir(liste)\r
-        else:\r
-            message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"\r
-            return message,None\r
-\r
-    def convertir(self, liste, f_conversion=None):\r
-        """ Cette méthode essaie de convertir les éléments de la liste avec la\r
-            fonction f_conversion si elle existe, et retourne la liste des\r
-            éléments dans le type voulu en cas de succès, sinon retourne None.\r
-        """\r
-        liste_valeurs = []\r
-        message = ""\r
-        for chaine in liste:\r
-            if f_conversion:\r
-                try:\r
-                    liste_valeurs.append(f_conversion(chaine))\r
-                except:\r
-                    message = "Impossible de convertir "+chaine+" dans le type attendu"\r
-                    return message,None\r
-            else:\r
-                liste_valeurs.append(chaine)\r
-        return message,liste_valeurs\r
-\r
-    def verif_valeurs(self, liste_valeurs):\r
-        """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque\r
-            élément est dans le domaine voulu.\r
-        """\r
-        message = ""\r
-        for valeur in liste_valeurs:\r
-            test = self.item.IsInIntervalle(valeur)\r
-            if test == 0:\r
-                intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])\r
-                message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"\r
-                return message\r
-        return message\r
-\r
-    def ajouter_valeurs(self, liste_valeurs):\r
-        """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""\r
-        liste = self.panel.Liste_valeurs.get_liste()\r
-        liste.extend(liste_valeurs)\r
+        self.but_save.configure(text="Ajouter",command=self.traite_selection)
+        # séparateur par défaut
+        self.separateur = ';'
+        # création de la zone de saisie du séparateur
+        l_separateurs_autorises = self.get_separateurs_autorises()
+        self.choix_sep = Pmw.ComboBox(self.frame_boutons,
+                                      label_text = "Séparateur :",
+                                      labelpos = 'w',
+                                      listheight = 100,
+                                      selectioncommand = self.choose_separateur,
+                                      scrolledlist_items = l_separateurs_autorises)
+        self.choix_sep.component('entry').configure(width=6)
+        self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')
+        self.choix_sep.selectitem(self.separateur)
+        # Replacement
+        self.but_quit.place_forget()
+        self.but_save.place_forget()
+       self.but_all  = Button(self.frame_boutons,text = "Tout Sélectionner", command=self.tout)
+        self.but_save.place(relx=0.6,rely=0.6,anchor='center')
+        self.but_quit.place(relx=0.8,rely=0.6,anchor='center')
+        self.but_all.place(relx=0.7,rely=0.2,anchor='center')
+       self.choose_separateur('espace')
+     
+
+    def get_separateurs_autorises(self):
+        """
+        Retourne la liste des séparateurs autorisés
+        """
+        return ['espace',';',',']
+
+    def choose_separateur(self,nom_sep):
+        """
+        Affecte à self.separateur le caractère séparateur correspondant à nom_sep
+        """
+        if nom_sep == 'espace' :
+            self.separateur = ' '
+        else:
+            self.separateur = nom_sep
+        
+    def tout(self):
+        liste=[]
+       texte=self.texte.splitlines()
+       for l in texte :
+           for mot in string.split(l,self.separateur):
+              if mot != '' and mot != ' ' and mot != self.separateur :
+                 liste.append(mot)
+       self.traite_selection(liste)
+
+    def traite_selection(self,liste=None):
+        """ Cette méthode effectue tous les traitements nécessaires pour vérifier
+            et affecter la liste de valeurs à l'objet réprésenté par self.item
+        """
+        # Récupère la liste des chaines de caractères de la zone sélectionnée
+       message=""
+       if liste == None:
+           message,liste = self.recupere_liste()
+        if self.test_probleme(message,"Sélectionnez des données") == 0:
+            return
+        # Vérifie que le nombre de données est dans les limites attendues
+        message = self.verif_liste(liste)
+        if self.test_probleme(message,"Vérifiez le nombre de données") == 0:
+            return
+        # Crée une liste de valeurs du type attendu
+        message,liste_valeurs = self.creation_liste_valeurs(liste)
+        if self.test_probleme(message,"Vérifiez le type des données") == 0:
+            return
+        # Vérifie que chaque valeur est dans le domaine exigé
+        message = self.verif_valeurs(liste_valeurs)
+        if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:
+            return
+        # Ajoute les valeurs dans la liste de valeurs du mot-clé
+        if self.cardinal != 1 :
+           nb=self.cardinal
+           l_valeurs=[]
+           # a ameliorer
+           if (len(liste_valeurs)%nb != 0):
+                message="La cardinalité n'est pas correcte"
+                self.test_probleme(message,"On attend des tuples")
+                return
+           for i in range(len(liste_valeurs)/nb) :
+               if (nb==2):
+                   t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1])
+               elif (nb ==3):
+                   t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1], liste_valeurs[i*nb+2])
+               else :
+                  print "probleme : prevenir la maintenance Eficas"
+                  return
+               l_valeurs.append(t)
+           liste_valeurs=l_valeurs
+        self.ajouter_valeurs(liste_valeurs)
+        self.appli.affiche_infos("Liste de valeurs acceptée")
+
+    def test_probleme(self, message, message_eficas):
+        """ Cette méthode affiche un message d'erreur si message != ''
+            et retourne 0, sinon retourne 1 sans rien afficher.
+        """
+        if message != "":
+            showinfo("Problème",message)
+            self.fenetre.tkraise()
+            self.appli.affiche_infos(message_eficas)
+            return 0
+        else:
+            return 1
+
+    def recupere_liste(self):
+        """ Cette méthode récupère le texte de la zone sélectionnée, construit et
+            retourne une liste avec les chaines qui se trouvent entre les séparateurs.
+            S'il n'y a pas de données selectionnées, elle retourne un message d'erreur
+            et une liste vide.
+        """
+        message = ""
+        try:
+            selection=self.fenetre.selection_get()
+        except:
+            message = "Pas de donnée sélectionnée"
+            return message,None
+        # les retours chariots doivent être interprétés comme des séparateurs
+        selection = string.replace(selection,'\n',self.separateur)
+        # on splitte la sélection suivant le caractère séparateur
+        liste_chaines = string.split(selection,self.separateur)
+        l_chaines = []
+        for chaine in liste_chaines:
+            chaine = string.strip(chaine)
+            if chaine != '' : l_chaines.append(chaine)
+        return message,l_chaines
+
+    def verif_liste(self, liste):
+        """ Cette méthode effectue des tests sur le nombre d'éléments de la liste
+            et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur
+            correspondant.
+        """
+        message = ""
+        # nombre d'éléments sélectionnés
+        nombre_elements = len(liste)
+        # nombre d'éléments déja dans la liste du panel
+        nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())
+        multiplicite = self.item.GetMultiplicite()
+        if (nombre_elements % multiplicite) != 0:
+            message = "Vous devez sélectionner "+str(multiplicite)+" * n données"
+            return message
+        nombre_valeurs = nombre_elements / multiplicite
+        cardinalite = self.item.GetMinMax()
+        if nombre_valeurs < cardinalite[0]:
+            message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"
+            return message
+        if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):
+            message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"
+            return message
+
+        return message
+
+    def creation_liste_valeurs(self, liste):
+        """ Cette méthode crée et retourne une liste de valeurs du type attendu
+            par le mot-clé. La liste de valeurs est créée à partir de la liste
+            de chaines de caractères transmise.
+        """
+        type_attendu = self.item.GetType()[0]
+        if type_attendu == 'R':
+            return self.convertir(liste, f_conversion= float)
+        elif type_attendu == 'I':
+            return self.convertir(liste, f_conversion= int)
+        elif type_attendu == 'TXM':
+            return self.convertir(liste)
+        else:
+            message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"
+            return message,None
+
+    def convertir(self, liste, f_conversion=None):
+        """ Cette méthode essaie de convertir les éléments de la liste avec la
+            fonction f_conversion si elle existe, et retourne la liste des
+            éléments dans le type voulu en cas de succès, sinon retourne None.
+        """
+        liste_valeurs = []
+       message = ""
+        for chaine in liste:
+            if f_conversion:
+                try:
+                    liste_valeurs.append(f_conversion(chaine))
+                except:
+                    message = "Impossible de convertir "+chaine+" dans le type attendu"
+                    return message,None
+            else:
+                liste_valeurs.append(chaine)
+        return message,liste_valeurs
+
+    def verif_valeurs(self, liste_valeurs):
+        """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque
+            élément est dans le domaine voulu.
+        """
+        message = ""
+        for valeur in liste_valeurs:
+            test = self.item.IsInIntervalle(valeur)
+            if test == 0:
+                intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])
+                message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"
+                return message
+        return message
+
+    def ajouter_valeurs(self, liste_valeurs):
+        """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""
+        liste = self.panel.Liste_valeurs.get_liste()
+        liste.extend(liste_valeurs)
         self.panel.Liste_valeurs.put_liste(liste)
 
+class FenetreDeParametre(Fenetre) :
+    def __init__(self,parent,item,appli,texte):
+        self.parent=parent
+        self.appli=appli
+        self.fenetre = Toplevel()
+        self.fenetre.configure(width = 250,height=100)
+        self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
+        self.fenetre.title("Parametres")
+        self.titre = "Parametres"
+        self.texte = string.replace(texte,'\r\n','\n')
+        fonte=fontes.standardcourier10
+
+        # définition des frames
+        self.frame_texte = Frame(self.fenetre)
+        self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.7)
+        # définition de la zone texte et du scrollbar
+        self.zone_texte = Text(self.frame_texte,font=fonte)
+        self.zone_texte.bind("<Key-Prior>", self.page_up)
+        self.zone_texte.bind("<Key-Next>", self.page_down)
+        self.zone_texte.bind("<Key-Up>", self.unit_up)
+        self.zone_texte.bind("<Key-Down>", self.unit_down)
+        self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
+        self.scroll_v.pack(side='right',fill ='y')
+        self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
+        self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
+        # affichage du texte
+        self.affiche_texte(self.texte)
+        self.zone_texte.config(state="disabled")
+
+       # définition des boutons
+       self.frame_boutons = Frame(self.fenetre)
+       self.frame_boutons.place(relheight=0.3,relx=0,rely=0.65,relwidth=1.)
+       self.label1 = Label(self.frame_boutons,text="surligner la")
+       self.label2 = Label(self.frame_boutons,text="ligne entière")
+       self.label1.place(relx=0.1,rely=0)
+       self.label2.place(relx=0.1,rely=0.5)
+       self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
+       self.but_save = Button(self.frame_boutons,text = "Choisir",command = self.Choisir)
+       self.but_save.place(relx=0.6,rely=0,relheight=1)
+       self.but_quit.place(relx=0.8,rely=0,relheight=1)
+
+
+    def Choisir(self):
+        try:
+            selection=self.zone_texte.selection_get()
+        except:
+            showerror("Pas de donnée sélectionnée",
+                       "Selectionner un parametre")
+        l_param = ""
+        for param in selection.splitlines():
+           nomparam=param[0:param.find("=")-1]
+            if nomparam != '' : 
+               l_param=l_param+nomparam+','
+       self.parent.entry.delete(0,Tkinter.END)
+       self.parent.entry.insert(0,l_param[0:-1])
+       self.parent.valid_valeur()
+       self.quit()
+
 class Formulaire:
-    """\r
+    """
     Cette classe permet de créer une boîte Dialog dans laquelle
-    on affiche un formulaire à remplir par l'utilisateur\r
+    on affiche un formulaire à remplir par l'utilisateur
     """
-    def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):\r
+    def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):
         if items in ((),[]) : return
         self.items = items
         self.titre = titre
@@ -364,25 +486,25 @@ class Formulaire:
         self.command = commande
         self.display()
 
-    def display(self):\r
+    def display(self):
         self.init_validateurs()
         self.init_fenetre()
         self.init_texte()
         self.init_items_formulaire()
         self.fenetre.activate(geometry='centerscreenalways')
-\r
-    def init_validateurs(self):\r
-        """\r
-        Crée le dictionnaire des validateurs des objets reconnus par le formulaire\r
-        """\r
-        self.d_validateurs = {}\r
-        self.d_validateurs['rep']  = self.repvalidator\r
-        self.d_validateurs['file'] = self.filevalidator\r
-        self.d_validateurs['cata']= self.catavalidator\r
+
+    def init_validateurs(self):
+        """
+        Crée le dictionnaire des validateurs des objets reconnus par le formulaire
+        """
+        self.d_validateurs = {}
+        self.d_validateurs['rep']  = self.repvalidator
+        self.d_validateurs['file'] = self.filevalidator
+        self.d_validateurs['cata']= self.catavalidator
         
-    def init_fenetre(self):\r
-        """\r
-        Crée la fenêtre Dialog\r
+    def init_fenetre(self):
+        """
+        Crée la fenêtre Dialog
         """
         if self.mode == 'query':
             buttons=('Valider','Annuler')
@@ -398,118 +520,123 @@ class Formulaire:
                                   buttons=buttons,
                                   defaultbutton = defaultbutton,
                                   title = self.titre,
-                                  command = self.execute)\r
+                                  command = self.execute)
         self.fenetre.withdraw()
         
-    def init_texte(self):\r
-        """\r
-        Crée le label qui affiche le texte à l'intérieur du panneau\r
+    def init_texte(self):
         """
-        fonte=fontes.standard\r
-        fr_texte = Frame(self.fenetre.interior(),height=60)\r
+        Crée le label qui affiche le texte à l'intérieur du panneau
+        """
+        fonte=fontes.standard
+        fr_texte = Frame(self.fenetre.interior(),height=60)
         fr_texte.pack(side='top',fill='x',expand=1)
         Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
-\r
-    def init_items_formulaire(self):\r
-        """\r
-        Crée et affiche les items dans la boîte de dialogue\r
-        """\r
-        self.radiobut = 0\r
-        self.widgets = []\r
-        self.item_widgets = {}\r
-        length_maxi = 0\r
+
+    def init_items_formulaire(self):
+        """
+        Crée et affiche les items dans la boîte de dialogue
+        """
+        self.radiobut = 0
+        self.widgets = []
+        self.item_widgets = {}
+        length_maxi = 0
         for item in self.items:
-            if len(item[0])>length_maxi : length_maxi = len(item[0])\r
-        window = self.fenetre.interior()\r
-        for item in self.items :\r
-            label,nature,nom_var,defaut = item\r
-            # création de la frame\r
-            fr_item = Frame(window,height=40,width=700)\r
-            fr_item.pack(side='top',fill='x',expand=1)\r
-            # création du label\r
-            Label(fr_item,text = label).place(relx=0.05,rely=0.4)\r
+            if len(item[0])>length_maxi : length_maxi = len(item[0])
+        window = self.fenetre.interior()
+        for item in self.items :
+           if len(item) == 4 :
+               label,nature,nom_var,defaut = item
+              chaine="Yes" 
+              chaine2="No"
+           else :
+               label,nature,nom_var,defaut,chaine,chaine2 = item
+            # création de la frame
+            fr_item = Frame(window,height=40,width=700)
+            fr_item.pack(side='top',fill='x',expand=1)
+            # création du label
+            Label(fr_item,text = label).place(relx=0.05,rely=0.4)
             if nature in ('rep','file','cata'):
-                # création de l'entry\r
-                e_item = Entry(fr_item) \r
-                e_item.place(relx=0.5,rely=0.4,relwidth=0.45)\r
-                self.widgets.append(e_item)\r
-                self.item_widgets[item] = e_item\r
-                if defaut : e_item.insert(0,str(defaut))\r
-            elif nature == 'YesNo':\r
-                # création de la StringVar\r
-                var = StringVar()\r
-                setattr(self,'item_'+nom_var,var)\r
-                var.set(defaut)\r
-                # création du radiobouton\r
-                rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')\r
-                rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')\r
-                rb1.place(relx=0.65,rely=0.5,anchor='center')\r
-                rb2.place(relx=0.80,rely=0.5,anchor='center')\r
-                self.widgets.append((rb1,rb2))\r
-                self.item_widgets[item] = var\r
-        # détermination de la méthode à appliquer sur les boutons\r
-        if self.mode == 'query':\r
-            function = self.active\r
-        elif self.mode == 'display':\r
-            function = self.inactive\r
-        else:\r
-            return\r
-        # on applique la méthode sur les boutons (activation ou désactivation)    \r
-        for widget in self.widgets :\r
-            if type(widget) == types.TupleType:\r
-                for widg in widget :\r
-                    apply(function,(widg,),{})\r
-            else:\r
-                apply(function,(widget,),{})\r
-\r
-    def active(self,widget):\r
-        """\r
-        Active le widget passé en argument\r
-        """\r
-        widget.configure(state='normal',bg='white')\r
-\r
-    def inactive(self,widget):\r
-        """\r
-        Inactive le widget passé en argument\r
-        """\r
-        if not isinstance(widget,Radiobutton) :\r
-            widget.configure(state='disabled',bg='gray95')\r
-        else :\r
-            widget.configure(state='disabled')\r
-\r
-# --------------------------------------------------------------------------------\r
-#       Validateurs des noms de répertoire, de fichiers et de catalogues\r
-# --------------------------------------------------------------------------------\r
+                # création de l'entry
+                e_item = Entry(fr_item) 
+                e_item.place(relx=0.5,rely=0.4,relwidth=0.45)
+                self.widgets.append(e_item)
+                self.item_widgets[item] = e_item
+                if defaut : e_item.insert(0,str(defaut))
+            elif nature == 'YesNo':
+                # création de la StringVar
+                var = StringVar()
+                setattr(self,'item_'+nom_var,var)
+                var.set(defaut)
+                # création du radiobouton
+                rb1 = Radiobutton(fr_item,text=chaine,variable=var,value='OUI')
+                rb2 = Radiobutton(fr_item,text=chaine2,variable=var,value='NON')
+                rb1.place(relx=0.65,rely=0.5,anchor='center')
+                rb2.place(relx=0.80,rely=0.5,anchor='center')
+                self.widgets.append((rb1,rb2))
+                self.item_widgets[item] = var
+        # détermination de la méthode à appliquer sur les boutons
+        if self.mode == 'query':
+            function = self.active
+        elif self.mode == 'display':
+            function = self.inactive
+        else:
+            return
+        # on applique la méthode sur les boutons (activation ou désactivation)  
+        for widget in self.widgets :
+            if type(widget) == types.TupleType:
+                for widg in widget :
+                    apply(function,(widg,),{})
+            else:
+                apply(function,(widget,),{})
+
+    def active(self,widget):
+        """
+        Active le widget passé en argument
+        """
+        widget.configure(state='normal',bg='white')
+
+    def inactive(self,widget):
+        """
+        Inactive le widget passé en argument
+        """
+        if not isinstance(widget,Radiobutton) :
+            widget.configure(state='disabled',bg='gray95')
+        else :
+            widget.configure(state='disabled')
+
+# --------------------------------------------------------------------------------
+#       Validateurs des noms de répertoire, de fichiers et de catalogues
+# -------------------------------------------------------------------------------
 
     def repvalidator(self,text):
-        """\r
-        Teste si text peut faire référence à un répertoire ou non\r
-        Retourne 1 si valide, 0 sinon\r
-        """\r
+        """
+        Teste si text peut faire référence à un répertoire ou non
+        Retourne 1 si valide, 0 sinon
+        """
         return os.path.isdir(text),'Répertoire introuvable : %s' %text
 
     def filevalidator(self,text):
-        """\r
-        Teste si text peut faire référence à un fichier ou non\r
-        Retourne 1 si valide, 0 sinon\r
-        """\r
+        """
+        Teste si text peut faire référence à un fichier ou non
+        Retourne 1 si valide, 0 sinon
+        """
         return os.path.isfile(text),'Fichier introuvable : %s' %text
-\r
-    def catavalidator(self,text):\r
-        """\r
-        Teste si  text est un chemin d'accès valide à un catalogue\r
-        Retourne 1 si valide, 0 sinon\r
-        """\r
-        return os.path.isfile(text),"Catalogue introuvable : %s" %text\r
-\r
-# --------------------------------------------------------------------------------\r
-#       Méthodes callbacks des boutons et de fin\r
-# --------------------------------------------------------------------------------\r
+
+    def catavalidator(self,text):
+        """
+        Teste si  text est un chemin d'accès valide à un catalogue
+        Retourne 1 si valide, 0 sinon
+        """
+        return os.path.isfile(text),"Catalogue introuvable : %s" %text
+
+# --------------------------------------------------------------------------------
+#       Méthodes callbacks des boutons et de fin
+# --------------------------------------------------------------------------------
         
-    def execute(self,txt):\r
-        """\r
-        Cette commande est activée à chaque clic sur un bouton.\r
-        Redirige l'action sur la bonne méthode en fonction du bouton activé\r
+    def execute(self,txt):
+        """
+        Cette commande est activée à chaque clic sur un bouton.
+        Redirige l'action sur la bonne méthode en fonction du bouton activé
         """
         if txt == 'Valider':
             self.fini()
@@ -522,26 +649,26 @@ class Formulaire:
             print "Nom de bouton inconnu"
             self.quit()
 
-    def fini(self):\r
-        """\r
-        Commande qui termine le panneau et sauvegarde les nouvelles options\r
-        dans l'objet resultat (dictionnaire)\r
+    def fini(self):
+        """
+        Commande qui termine le panneau et sauvegarde les nouvelles options
+        dans l'objet resultat (dictionnaire)
         """
         dico={}
-        for item,widget in self.item_widgets.items():\r
-            nom_var = item[2]\r
+        for item,widget in self.item_widgets.items():
+            nom_var = item[2]
             type_var = item[1]
-            valeur = widget.get()\r
-            if self.d_validateurs.has_key(type_var):\r
-                test = self.d_validateurs[type_var](valeur)\r
-                if not test :\r
-                    # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode\r
-                    # sans tuer la fenêtre bien sûr\r
-                    widget.selection_range(0,END)\r
+            valeur = widget.get()
+            if self.d_validateurs.has_key(type_var):
+                test = self.d_validateurs[type_var](valeur)
+                if not test :
+                    # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode
+                    # sans tuer la fenêtre bien sûr
+                    widget.selection_range(0,END)
                     return
             dico[nom_var] = valeur
         self.fenetre.destroy()    
-        self.resultat=dico\r
+        self.resultat=dico
         
     def quit(self):
         self.fenetre.destroy()
@@ -550,7 +677,8 @@ class Formulaire:
 class ListeChoix :
     """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
         en passant les commandes à lancer suivant différents bindings """
-    def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''):
+    def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre='',
+                 optionReturn=None, fonte_titre=fontes.standard_gras_souligne):
         self.parent = parent
         self.page = page
         self.liste = liste
@@ -562,6 +690,8 @@ class ListeChoix :
         self.active = active
         self.titre = titre
         self.filtre = filtre
+        self.optionReturn = optionReturn
+       self.fonte_titre=fonte_titre
         self.init()
 
     def init(self):        
@@ -576,10 +706,9 @@ class ListeChoix :
     def make_label_titre(self):
         """ Crée le label correspondant au titre """
         if self.titre == '' : return
-        fonte_titre = fontes.standard_gras_souligne
         self.label = Label(self.page,
                            text = self.titre,
-                           font = fonte_titre)
+                           font = self.fonte_titre)
         self.label.pack(side='top',pady=2)
         
     def make_entry_filtre(self):
@@ -598,6 +727,7 @@ class ListeChoix :
         self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
         self.MCbox.configure(yscrollcommand=self.MCscroll.set)
 
+
     def affiche_liste(self):
         """ Affiche la liste dans la fenêtre"""
         liste_labels=[]
@@ -612,8 +742,23 @@ class ListeChoix :
           elif type(objet) in (types.StringType,types.IntType):
               mot = objet
           elif type(objet) == types.FloatType :
-              #mot = repr_float(objet)
-              mot = str(objet)
+              mot = self.parent.get_valeur_texte(objet)
+              if mot == "" :
+                 mot = str(objet)
+          elif type(objet) == types.TupleType :
+              mot="("
+              premier=1
+              for val in objet:
+                if (not premier):
+                  mot=mot+"," 
+                 else:
+                   premier=0
+                 valtexte = self.parent.get_valeur_texte(val)
+                 if valtexte != "" :
+                    mot=mot+valtexte
+                 else:
+                    mot=mot+str(val)
+              mot=mot+")"
           else:
               mot=`objet`
           label = Label(self.MCbox,
@@ -625,6 +770,13 @@ class ListeChoix :
                                    window=label,
                                    stretch = 1)
           self.MCbox.insert(END,'\n')
+          if self.optionReturn != None :
+              label.bind("<Return>",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c))
+              label.bind("<KP_Enter>",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c))
+          label.bind("<Key-Right>",lambda e,s=self,x=objet,l=label : s.selectNextItem(x,l))
+          label.bind("<Key-Down>",lambda e, s=self,x=objet,l=label : s.selectNextItem(x,l))
+          label.bind("<Key-Left>" ,lambda e,s=self,x=objet,l=label  : s.selectPrevItem(x,l))
+          label.bind("<Key-Up>" ,lambda e,s=self,x=objet,l=label  : s.selectPrevItem(x,l))
           if self.active == 'oui':
               label.bind(self.liste_commandes[0][0],lambda e,s=self,c=self.liste_commandes[0][1],x=objet,l=label : s.selectitem(x,l,c))
               label.bind(self.liste_commandes[1][0],lambda e,s=self,c=self.liste_commandes[1][1],x=objet,l=label : s.deselectitem(l,x,c))
@@ -638,23 +790,85 @@ class ListeChoix :
 
         self.MCbox.config(state=DISABLED)
         self.selection = None
+        self.dontselect=0
+        for event,callback in self.liste_commandes:
+            if event == "<Enter>":
+               self.selection=None,None,callback
+               break
+
+    def clear_marque(self):
+        try:
+          self.dico_labels[self.arg_selected].configure(bg='gray95',fg='black')
+          self.arg_selected = ''
+       except :
+         pass
+
+    def surligne(self,marque):
+        try :
+          self.highlightitem(self.dico_labels[marque])
+           self.arg_selected = marque
+       except:
+          pass
+
+    def chooseitemsurligne(self,mot,label,commande):
+        """ Active la méthode de choix passée en argument"""
+        try:
+           mot=self.arg_selected
+           commande(mot)
+        except AsException,e:
+           raison=str(e)
+           showerror(raison.split('\n')[0],raison)
 
     def chooseitem(self,mot,label,commande):
         """ Active la méthode de choix passée en argument"""
-        commande(mot)
+        try:
+           commande(mot)
+        except AsException,e:
+           raison=str(e)
+           showerror(raison.split('\n')[0],raison)
+
+    def selectNextItem(self,mot,label):
+        index=self.liste.index(mot)
+        indexsuivant=index+1
+       if indexsuivant > len(self.liste) -1:
+          indexsuivant=0
+        motsuivant=self.liste[indexsuivant]
+        labelsuivant=self.dico_labels[motsuivant]
+        index = self.MCbox.index(labelsuivant)
+        self.MCbox.see(index)
+        self.selectthis(motsuivant,labelsuivant,self.selection[2],)
+        self.dontselect=1
+           
+    def selectPrevItem(self,mot,label):
+        index=self.liste.index(mot)
+        indexprec=index-1
+        motprec=self.liste[indexprec]
+        labelprec=self.dico_labels[motprec]
+        index = self.MCbox.index(labelprec)
+        self.MCbox.see(index)
+        self.selectthis(motprec,labelprec,self.selection[2],)
+        self.dontselect=1
         
-    def selectitem(self,mot,label,commande) :
-        """ Met l'item sélectionné (représenté par son label) en surbrillance
-            et lance la commande associée au double-clic"""
+    def selectthis(self,mot,label,commande) :
+       self.clear_marque()
         if self.selection != None :
             self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
         self.highlightitem(label)
         self.selection = (mot,label,commande)
         self.arg_selected = mot
-        commande(mot)
+        if commande : commande(mot)
+
+    def selectitem(self,mot,label,commande) :
+        """ Met l'item sélectionné (représenté par son label) en surbrillance
+            et lance la commande associée au double-clic"""
+        if self.dontselect:
+           self.dontselect=0
+           return
+        self.selectthis(mot,label,commande)
 
     def highlightitem(self,label) :
         """ Met l'item représenté par son label en surbrillance """
+        label.focus_set()
         label.configure(bg='#00008b',fg='white')
         
     def markitem(self,label):
@@ -663,9 +877,23 @@ class ListeChoix :
         
     def deselectitem(self,label,mot='',commande=None) :
         """ Remet l'item (représenté par son label) en noir"""
-        label.configure(bg='gray95',fg='black')
+        if label:label.configure(bg='gray95',fg='black')
         self.arg_selected = ''
-        if commande != None : commande(mot)
+        if commande and mot : commande(mot)
+
+    def cherche_selected_item(self):
+        index=self.MCbox.index(self.selection[1])
+        lign,col=map(int,string.split(index,'.'))
+        return lign
+
+    def remove_selected_item(self):
+       try :
+           index=self.MCbox.index(self.selection[1])
+       except :
+           index=self.MCbox.index(self.dico_labels[self.arg_selected] )
+        lign,col=map(int,string.split(index,'.'))
+        del self.liste[lign-1]
+        self.affiche_liste()
 
     def entry_changed(self,event=None):
         """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
@@ -675,29 +903,36 @@ class ListeChoix :
         FILTRE = string.upper(filtre)
         for arg in self.liste :
             if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
-                self.highlightitem(self.dico_labels[arg])
-                index = self.MCbox.index(self.dico_labels[arg])
+                label=self.dico_labels[arg]
+                index = self.MCbox.index(label)
                 self.MCbox.see(index)
-                self.arg_selected = arg
+                self.selectitem(arg,label,self.selection[2])
                 break
 
-    def get_liste_old(self):
-        return self.liste
+        #try :
+          #self.dico_labels[self.arg_selected].focus_set()
+        #except :
+          #pass
+
 
+    # PN attention à la gestion des paramétres
+    # cela retourne H = 1 , et ni H, ni 1
+    #            print repr(val)
+    #            print val.__class__.__name__
     def get_liste(self):
         l=[]
         for val in self.liste:
-            try:
-                val = eval(val)
-                l.append(val)
-            except:
+#            try:
+#                v = eval(val)
+#              l.append(v)
+#            except:
                 l.append(val)
         return l
     
     def put_liste(self,liste):
         self.liste = liste
         self.affiche_liste()
-        
+
 class Affichage :
   """ Cette classe permet d'afficher au lancement d'EFICAS le message
       d'attente et la barre de progression"""
@@ -751,9 +986,9 @@ class Affichage :
       self.progress.update()
 
 class Ask_Format_Fichier :
-    """\r
+    """
     Cette classe permet de créer une fenêtre Toplevel dans laquelle
-    on propose le choix du format de fichier de commandes à ouvrir\r
+    on propose le choix du format de fichier de commandes à ouvrir
     """
     def __init__(self,appli):
         self.fenetre = Toplevel()
@@ -873,9 +1108,16 @@ class ListeChoixParGroupes(ListeChoix) :
         Cette classe est utilisée pour afficher une liste de commandes classées par
         groupes. L'utilisateur peut réaliser des actions de selection
         qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
+        Exemple de binding:
+           liste_commandes = (("<Enter>",self.selectCmd),
+                              ("<Leave>",self.deselectCmd),
+                              ("<Double-Button-1>",self.defCmd))
+        Il s'agit d'une liste de doublets dont le premier element est un evenement et le 
+        deuxieme un callback a appeler sur l'evenement en question.
+
     """
     def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
-                      active ='oui',filtre='non',titre=''):
+                      active ='oui',filtre='non',titre='',optionReturn=None,fonte_titre=fontes.standard_gras_souligne):
         self.parent = parent
         self.page = page
         self.liste_groupes = liste_groupes
@@ -888,11 +1130,13 @@ class ListeChoixParGroupes(ListeChoix) :
         self.active = active
         self.titre = titre
         self.filtre = filtre
+        self.optionReturn = optionReturn
+        self.fonte_titre=fonte_titre
         self.init()
 
     def affiche_liste(self):
         """ Affiche la liste dans la fenêtre"""
-        i=0
+        liste_labels=[]
         self.MCbox.config(state=NORMAL)
         self.MCbox.delete(1.0,END)
         for grp in self.liste_groupes:
@@ -906,6 +1150,7 @@ class ListeChoixParGroupes(ListeChoix) :
                         fg = 'black',bg = 'gray95',justify = 'left')
            # On stocke la relation entre le nom de la commande et le label
            self.dico_labels[grp]=label
+           liste_labels.append(label)
            self.MCbox.window_create(END,
                                    window=label,
                                    stretch = 1)
@@ -920,18 +1165,99 @@ class ListeChoixParGroupes(ListeChoix) :
                                    window=label,
                                    stretch = 1)
               self.MCbox.insert(END,'\n')
+
+              def null(*tp,**args): return
+
               if self.active == 'oui':
-                  label.bind(self.liste_commandes[0][0],
-                         lambda e,s=self,c=self.liste_commandes[0][1],x=cmd,l=label : s.selectitem(x,l,c))
-                  label.bind(self.liste_commandes[1][0],
-                         lambda e,s=self,c=self.liste_commandes[1][1],x=cmd,l=label : s.deselectitem(l,x,c))
-                  label.bind(self.liste_commandes[2][0],
-                         lambda e,s=self,c=self.liste_commandes[2][1],x=cmd,l=label : s.chooseitem(x,l,c))
-              # On marque les items specifies dans liste_marques
-              #if i in self.liste_marques : self.markitem(label)
-              i=i+1
+                  # Traitement par defaut des evenements
+                  label.bind("<Enter>",lambda e,s=self,c=null,x=cmd,l=label: s.selectitem(x,l,c))
+                  label.bind("<Leave>",lambda e,s=self,c=null,x=cmd,l=label: s.deselectitem(l,x,c))
+                  label.bind("<Double-Button-1>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
+                  label.bind("<Return>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
+                  label.bind("<KP_Enter>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
+                  label.bind("<Key-Right>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectNextItem(x,l,c,gr,x))
+                  label.bind("<Key-Down>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectNextItem(x,l,c,gr,x))
+                  label.bind("<Key-Left>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectPrevItem(x,l,c,gr,x))
+                  label.bind("<Key-Up>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectPrevItem(x,l,c,gr,x))
+
+                  # Si des callbacks sont definis on les utilise
+                  for event,callback in self.liste_commandes:
+                      if event == "<Enter>":
+                         label.bind("<Enter>",lambda e,s=self,c=callback,x=cmd,l=label: s.selectitem(x,l,c))
+                      elif event == "<Leave>":
+                         label.bind("<Leave>",lambda e,s=self,c=callback,x=cmd,l=label: s.deselectitem(l,x,c))
+                      elif event == "<Double-Button-1>":
+                         label.bind("<Double-Button-1>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
+                      elif event == "<Return>":
+                         label.bind("<Return>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
+                      elif event == "<KP_Enter>":
+                         label.bind("<KP_Enter>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
+                      elif event == "<Key-Right>":
+                         label.bind("<Key-Right>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectNextItem(x,l,c,gr,x))
+                      elif event == "<Key-Down>":
+                         label.bind("<Key-Down>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectNextItem(x,l,c,gr,x))
+                      elif event == "<Key-Left>":
+                         label.bind("<Key-Left>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectPrevItem(x,l,c,gr,x))
+                      elif event == "<Key-Up>":
+                         label.bind("<Key-Up>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectPrevItem(x,l,c,gr,x))
+                      else:
+                         label.bind(event,lambda e,s=self,c=callback,x=cmd,l=label: c())
+
+        for marque in self.liste_marques:
+           try:
+              self.markitem(liste_labels[marque])
+           except:
+              pass
+
         self.MCbox.config(state=DISABLED)
         self.selection = None
+        self.dontselect=0
+        for event,callback in self.liste_commandes:
+            if event == "<Enter>":
+               self.selection=None,None,callback
+               break
+
+    def selectPrevItem(self,mot,label,callback,group,cmd):
+        g=self.liste_groupes.index(group)
+        liste_commandes=self.dict_groupes[group]
+        c=liste_commandes.index(cmd)
+        if c > 0:
+           co=liste_commandes[c-1]
+        else:
+           # debut de liste. On passe au groupe precedent
+           if g > 0:
+              gr=self.liste_groupes[g-1]
+              co=self.dict_groupes[gr][-1]
+           else:
+              # debut des groupes. On ne fait rien
+              return
+        # On a trouve l'item precedent
+        labelsuivant=self.dico_labels[co]
+        index = self.MCbox.index(labelsuivant)
+        self.MCbox.see(index)
+        self.selectthis(co,labelsuivant,self.selection[2],)
+        self.dontselect=1
+
+    def selectNextItem(self,mot,label,callback,group,cmd):
+        g=self.liste_groupes.index(group)
+        liste_commandes=self.dict_groupes[group]
+        c=liste_commandes.index(cmd)
+        try:
+           co=liste_commandes[c+1]
+        except:
+           # fin de liste. On passe au groupe suivant
+           try:
+              gr=self.liste_groupes[g+1]
+              co=self.dict_groupes[gr][0]
+           except:
+              # fin des groupes. On ne fait rien
+              return
+        # On a trouve l'item suivant
+        labelsuivant=self.dico_labels[co]
+        index = self.MCbox.index(labelsuivant)
+        self.MCbox.see(index)
+        self.selectthis(co,labelsuivant,self.selection[2],)
+        self.dontselect=1
 
     def entry_changed(self,event=None):
         """ 
@@ -939,6 +1265,7 @@ class ListeChoixParGroupes(ListeChoix) :
             de l'entry et frappe <Return>
         """
         if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
+
         filtre = self.entry.get()+"*"
         FILTRE = string.upper(filtre)
         #
@@ -947,20 +1274,21 @@ class ListeChoixParGroupes(ListeChoix) :
         #
         for grp in self.liste_groupes:
             if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
-                index = self.MCbox.index(self.dico_labels[grp])
+                cmd=self.dict_groupes[grp][0]
+                label=self.dico_labels[cmd]
+                index = self.MCbox.index(label)
                 self.MCbox.see(index)
-                # On ne selectionne pas le groupe
-                #self.arg_selected = grp
+                self.selectitem(cmd,label,self.selection[2])
                 # On a trouve un groupe on arrete la recherche
                 return
 
         for grp in self.liste_groupes:
            for cmd in self.dict_groupes[grp] :
               if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
-                 self.highlightitem(self.dico_labels[cmd])
-                 index = self.MCbox.index(self.dico_labels[cmd])
+                 label=self.dico_labels[cmd]
+                 index = self.MCbox.index(label)
                  self.MCbox.see(index)
-                 self.arg_selected = cmd
+                 self.selectitem(cmd,label,self.selection[2])
                  # On a trouve une commande  on arrete la recherche
                  return