Salome HOME
pour elts de structure
[tools/eficas.git] / Editeur / widgets.py
index 9baae75d247a1533d8183801987f8cafb3e8a694..0b39e7215e21f9d184c6c6ccb10f93fd95349638 100644 (file)
@@ -57,6 +57,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)
@@ -88,6 +89,7 @@ class Fenetre :
         # affichage du texte
         self.affiche_texte(self.texte)
         centerwindow(self.fenetre)
+        self.fenetre.deiconify()
 
     def page_up(self,event):
         event.widget.yview_scroll(-1, "page")
@@ -130,7 +132,7 @@ 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")
@@ -206,7 +208,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,
@@ -225,6 +227,7 @@ class FenetreDeSelection(Fenetre):
         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):
@@ -247,7 +250,8 @@ class FenetreDeSelection(Fenetre):
        texte=self.texte.splitlines()
        for l in texte :
            for mot in string.split(l,self.separateur):
-              liste.append(mot)
+              if mot != '' and mot != ' ' and mot != self.separateur :
+                 liste.append(mot)
        self.traite_selection(liste)
 
     def traite_selection(self,liste=None):
@@ -666,7 +670,7 @@ 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):
         self.parent = parent
         self.page = page
         self.liste = liste
@@ -678,6 +682,7 @@ class ListeChoix :
         self.active = active
         self.titre = titre
         self.filtre = filtre
+        self.optionReturn = optionReturn
         self.init()
 
     def init(self):        
@@ -714,6 +719,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=[]
@@ -728,17 +734,22 @@ 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
-                  mot=mot+str(val)
+                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`
@@ -751,6 +762,11 @@ 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-Left>" ,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))
@@ -779,6 +795,15 @@ class ListeChoix :
        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"""
         try:
@@ -787,6 +812,47 @@ class ListeChoix :
            raison=str(e)
            showerror(raison.split('\n')[0],raison)
         
+    def selectNextItem(self,mot,label):
+        try :
+           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]
+           self.clear_marque()
+           if self.selection != None :
+              self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
+              self.selection = (mot,label,self.selection[2])
+           index = self.MCbox.index(labelsuivant)
+           self.MCbox.see(index)
+           self.highlightitem(labelsuivant)
+           self.arg_selected=motsuivant
+           labelsuivant.focus_set()
+        # PN il faut faire quelque chose pour être dans la fenetre
+        except:
+           pass
+           
+    def selectPrevItem(self,mot,label):
+        try :
+           index=self.liste.index(mot)
+           indexprec=index-1
+           motprec=self.liste[indexprec]
+           labelprec=self.dico_labels[motprec]
+           self.clear_marque()
+           if self.selection != None :
+              self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
+              self.selection = (mot,label,self.selection[2])
+           index = self.MCbox.index(labelprec)
+           self.MCbox.see(index)
+           self.highlightitem(labelprec)
+           self.arg_selected=motprec
+           labelprec.focus_set()
+        # PN il faut faire quelque chose pour être dans la fenetre
+        except:
+           pass
+           
+        
     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"""
@@ -800,6 +866,7 @@ class ListeChoix :
 
     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):
@@ -835,9 +902,16 @@ class ListeChoix :
                 index = self.MCbox.index(self.dico_labels[arg])
                 self.MCbox.see(index)
                 self.arg_selected = arg
+                self.dico_labels[self.arg_selected].focus_set()
                 break
 
-    def get_liste_old(self):
+        #try :
+          #self.dico_labels[self.arg_selected].focus_set()
+        #except :
+          #pass
+
+    def get_liste_BAK(self):
+        raise "OBSOLETE"
         return self.liste
 
     # PN attention à la gestion des paramétres
@@ -1033,9 +1107,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):
         self.parent = parent
         self.page = page
         self.liste_groupes = liste_groupes
@@ -1048,6 +1129,7 @@ class ListeChoixParGroupes(ListeChoix) :
         self.active = active
         self.titre = titre
         self.filtre = filtre
+        self.optionReturn = optionReturn
         self.init()
 
     def affiche_liste(self):
@@ -1081,13 +1163,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:
@@ -1098,12 +1210,68 @@ class ListeChoixParGroupes(ListeChoix) :
         self.MCbox.config(state=DISABLED)
         self.selection = None
 
+    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
+        self.clear_marque()
+        labelsuivant=self.dico_labels[co]
+        if self.selection != None :
+           self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
+           self.selection = (co,labelsuivant,self.selection[2])
+        index = self.MCbox.index(labelsuivant)
+        self.MCbox.see(index)
+        self.arg_selected=co
+        self.highlightitem(labelsuivant)
+        labelsuivant.focus_set()
+        callback(co)
+
+    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
+        self.clear_marque()
+        labelsuivant=self.dico_labels[co]
+        if self.selection != None :
+           self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
+           self.selection = (co,labelsuivant,self.selection[2])
+        index = self.MCbox.index(labelsuivant)
+        self.MCbox.see(index)
+        self.arg_selected=co
+        self.highlightitem(labelsuivant)
+        labelsuivant.focus_set()
+        callback(co)
+
     def entry_changed(self,event=None):
         """ 
             Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
             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)
         #
@@ -1112,10 +1280,12 @@ class ListeChoixParGroupes(ListeChoix) :
         #
         for grp in self.liste_groupes:
             if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
+                self.highlightitem(self.dico_labels[grp])
                 index = self.MCbox.index(self.dico_labels[grp])
                 self.MCbox.see(index)
                 # On ne selectionne pas le groupe
                 #self.arg_selected = grp
+                self.dico_labels[grp].focus_set()
                 # On a trouve un groupe on arrete la recherche
                 return
 
@@ -1126,6 +1296,7 @@ class ListeChoixParGroupes(ListeChoix) :
                  index = self.MCbox.index(self.dico_labels[cmd])
                  self.MCbox.see(index)
                  self.arg_selected = cmd
+                 self.dico_labels[self.arg_selected].focus_set()
                  # On a trouve une commande  on arrete la recherche
                  return