]> SALOME platform Git repositories - tools/eficas.git/blobdiff - Editeur/widgets.py
Salome HOME
PN
[tools/eficas.git] / Editeur / widgets.py
index 6840f4120470d2fa7067959c896719089521ecd5..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
@@ -27,6 +28,7 @@ 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
 
@@ -56,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)
@@ -80,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")
@@ -129,13 +134,19 @@ class Fenetre :
                                initialdir = self.appli.CONFIGURATION.initialdir,
                                title="Sauvegarde du "+self.titre)
         if file :
-            if not save_in_file(file,self.texte) :
+            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
@@ -184,8 +195,14 @@ class FenetreDeSelection(Fenetre):
     """ 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=""):
+    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
@@ -193,7 +210,7 @@ class FenetreDeSelection(Fenetre):
         self.fenetre.title(titre)
         self.but_save.configure(text="Ajouter",command=self.traite_selection)
         # séparateur par défaut
-        self.separateur = ";"
+        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,
@@ -208,8 +225,12 @@ class FenetreDeSelection(Fenetre):
         # Replacement
         self.but_quit.place_forget()
         self.but_save.place_forget()
-        self.but_save.place(relx=0.6,rely=0.5,anchor='center')
-        self.but_quit.place(relx=0.8,rely=0.5,anchor='center')
+       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):
         """
@@ -226,12 +247,23 @@ class FenetreDeSelection(Fenetre):
         else:
             self.separateur = nom_sep
         
-    def traite_selection(self):
+    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,liste = self.recupere_liste()
+       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
@@ -247,6 +279,24 @@ class FenetreDeSelection(Fenetre):
         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")
 
@@ -331,7 +381,7 @@ class FenetreDeSelection(Fenetre):
             éléments dans le type voulu en cas de succès, sinon retourne None.
         """
         liste_valeurs = []
-        message = ""
+       message = ""
         for chaine in liste:
             if f_conversion:
                 try:
@@ -362,6 +412,64 @@ class FenetreDeSelection(Fenetre):
         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:
     """
     Cette classe permet de créer une boîte Dialog dans laquelle
@@ -436,7 +544,12 @@ class Formulaire:
             if len(item[0])>length_maxi : length_maxi = len(item[0])
         window = self.fenetre.interior()
         for item in self.items :
-            label,nature,nom_var,defaut = item
+           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)
@@ -455,8 +568,8 @@ class Formulaire:
                 setattr(self,'item_'+nom_var,var)
                 var.set(defaut)
                 # création du radiobouton
-                rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')
-                rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')
+                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))
@@ -564,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
@@ -576,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):        
@@ -590,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):
@@ -612,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=[]
@@ -626,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,
@@ -639,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))
@@ -652,6 +790,34 @@ 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"""
@@ -660,19 +826,49 @@ class ListeChoix :
         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):
@@ -681,13 +877,21 @@ 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 remove_selected_item(self):
+    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()
 
@@ -699,14 +903,17 @@ 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
@@ -725,7 +932,7 @@ class ListeChoix :
     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"""
@@ -901,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
@@ -916,6 +1130,8 @@ 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):
@@ -949,13 +1165,43 @@ 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))
+                  # 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:
@@ -965,6 +1211,53 @@ class ListeChoixParGroupes(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 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):
         """ 
@@ -972,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)
         #
@@ -980,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