1 # -*- coding: utf-8 -*-
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
21 # ----------------------------------------------------------
22 # Cette classe sert à définir les widgets utilisés par
24 # ----------------------------------------------------------
29 import os,sys,re,string
32 from tkFileDialog import *
33 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
37 from utils import save_in_file
38 from centerwindow import centerwindow
40 from Noyau.N_utils import repr_float
41 from Accas import AsException
43 # Surcharge de la fonction askyesno qui retourne un resultat errone en Python 2.3 avec Tk 8.4
44 # et Tkinter.wantobject==1
46 def askyesno(title=None, message=None, **options):
47 "Ask a question; return true if the answer is yes"
48 s = tkMessageBox._show(title, message, tkMessageBox.QUESTION, tkMessageBox.YESNO, **options)
49 if s == tkMessageBox.YES:return 1
50 if s == tkMessageBox.NO:return 0
56 """ Cette classe permet de créer une fenêtre Toplevel dans laquelle
57 on peut afficher un texte et qui permet de le sauver"""
58 def __init__(self,appli,titre="",texte="",wrap=WORD,width=100,height=30):
60 if self.appli.test==1 : return
61 self.fenetre = Toplevel()
62 self.fenetre.withdraw()
63 #self.fenetre.configure(width = 800,height=500)
64 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
65 self.fenetre.title("Visualisation du "+titre)
66 self.texte = string.replace(texte,'\r\n','\n')
68 fonte=fontes.standardcourier10
69 # définition des frames
70 self.frame_texte = Frame(self.fenetre)
71 self.frame_boutons = Frame(self.fenetre)
72 #self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.9)
73 #self.frame_boutons.place(relheight=0.1,relx=0,rely=0.9,relwidth=1.)
74 # définition de la zone texte et du scrollbar
75 self.zone_texte = Text(self.frame_texte,font=fonte,wrap=wrap,
76 height=height,width=width)
77 self.zone_texte.bind("<Key-Prior>", self.page_up)
78 self.zone_texte.bind("<Key-Next>", self.page_down)
79 self.zone_texte.bind("<Key-Up>", self.unit_up)
80 self.zone_texte.bind("<Key-Down>", self.unit_down)
81 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
82 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
83 self.scroll_v.pack(side='right',fill ='y')
84 #self.scroll_h.pack(side='bottom',fill ='x')
85 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
86 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
87 # définition des boutons
88 self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit,
90 self.but_save = Button(self.frame_boutons,text = "Sauver",command = self.save)
91 #self.but_quit.place(relx=0.4,rely=0.5,anchor='center')
92 #self.but_save.place(relx=0.6,rely=0.5,anchor='center')
93 self.but_quit.pack(side='left',padx=25, pady=5)
94 self.but_save.pack(side='right',padx=25, pady=5)
95 self.frame_texte.pack(side='top',fill='both',expand=1)
96 self.frame_boutons.pack(side='bottom')
97 self.zone_texte.focus_set()
98 self.fenetre.bind('<Return>',self.quit) #dismiss window
101 self.affiche_texte(self.texte)
102 self.zone_texte.config(state=DISABLED)
103 centerwindow(self.fenetre)
104 self.fenetre.deiconify()
106 def page_up(self,event):
107 event.widget.yview_scroll(-1, "page")
108 return "break" #Pour eviter la propagation de l'evenement a la fenetre principale
109 def page_down(self,event):
110 event.widget.yview_scroll(1, "page")
111 return "break" #Pour eviter la propagation de l'evenement a la fenetre principale
112 def unit_up(self,event):
113 event.widget.yview_scroll(-1, "unit")
114 return "break" #Pour eviter la propagation de l'evenement a la fenetre principale
115 def unit_down(self,event):
116 event.widget.yview_scroll(1, "unit")
117 return "break" #Pour eviter la propagation de l'evenement a la fenetre principale
120 self.fenetre.grab_set()
121 self.zone_texte.focus_set()
122 self.fenetre.wait_window(self.fenetre)
124 def quit(self,event=None):
125 self.fenetre.destroy()
126 return "break" #Pour eviter la propagation de l'evenement a la fenetre principale
128 def efface_scroll(self):
129 """ Efface le scroll lorsqu'il n'est pas nécessaire : ne marche pas"""
130 self.scroll_v.pack_forget()
131 #self.scroll_h.pack_forget()
133 def affiche_texte(self,texte):
134 """ Affiche le texte dans la fenêtre """
136 self.zone_texte.insert(END,texte)
138 self.fenetre.update_idletasks()
139 x0,y0,x1,y1 = self.zone_texte.bbox(END)
140 if (y1-y0) < 300 : self.efface_scroll()
145 """ Permet de sauvegarder le texte dans un fichier dont on a demandé le nom
147 file = asksaveasfilename(parent=self.fenetre,defaultextension = '.comm',
148 #initialdir = self.appli.CONFIGURATION.rep_user,
149 initialdir = self.appli.CONFIGURATION.initialdir,
150 title="Sauvegarde du "+self.titre)
152 if not save_in_file(file,self.texte,None) :
153 showerror("Sauvegarde impossible",
154 "Impossible de sauvegarder le texte dans le fichier spécifié\n"+
155 "Vérifiez les droits d'écriture",parent=self.fenetre)
157 showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file,parent=self.fenetre)
161 self.fenetre.destroy()
165 class FenetreSurLigneWarning(Fenetre):
167 def affiche_texte(self,texte):
168 """ Affiche le texte dans la fenêtre """
171 texte_cr=texte.splitlines()
175 self.zone_texte.insert(END,l)
176 if (l.find("WARNING") > -1) or (l.find("ERROR") > -1) :
177 self.zone_texte.tag_add( "Rouge", str(ligne)+".0", "end-1c" )
178 self.zone_texte.tag_config("Rouge", foreground='red')
180 self.fenetre.update_idletasks()
181 x0,y0,x1,y1 = self.zone_texte.bbox(END)
182 if (y1-y0) < 300 : self.efface_scroll()
186 class FenetreYesNo(Fenetre):
187 def __init__(self,appli,titre="",texte="",yes="Yes",no="No"):
189 self.fenetre = Toplevel()
190 self.fenetre.configure(width = 800,height=500)
191 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
192 self.fenetre.title(titre)
193 self.texte = string.replace(texte,'\r\n','\n')
195 fonte=fontes.standardcourier10
196 # définition des frames
197 self.frame_texte = Frame(self.fenetre)
198 self.frame_boutons = Frame(self.fenetre)
199 self.frame_boutons.place(relx=0,rely=0, relwidth=1.,relheight=0.1)
200 self.frame_texte.place( relx=0,rely=0.1, relwidth=1, relheight=0.9)
201 # définition de la zone texte et du scrollbar
202 self.zone_texte = Text(self.frame_texte,font=fonte)
203 self.zone_texte.bind("<Key-Prior>", self.page_up)
204 self.zone_texte.bind("<Key-Next>", self.page_down)
205 self.zone_texte.bind("<Key-Up>", self.unit_up)
206 self.zone_texte.bind("<Key-Down>", self.unit_down)
207 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
208 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
209 self.scroll_v.pack(side='right',fill ='y')
210 #self.scroll_h.pack(side='bottom',fill ='x')
211 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
212 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
213 # définition des boutons
214 self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes)
215 self.but_no = Button(self.frame_boutons,text = no,command = self.no)
216 self.but_yes.place(relx=0.4,rely=0.5,anchor='center')
217 self.but_no.place(relx=0.6,rely=0.5,anchor='center')
219 self.affiche_texte(self.texte)
220 centerwindow(self.fenetre)
230 class FenetreDeSelection(Fenetre):
231 """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.
232 Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.
234 def __init__(self,panel,item,appli,titre="",texte="",cardinal=1):
235 Fenetre.__init__(self,appli,titre=titre,texte=texte)
236 self.frame_boutons.place_forget()
237 self.frame_texte.place_forget()
238 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.8)
239 self.frame_boutons.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
241 self.cardinal=cardinal
242 self.fenetre.configure(width = 320,height=400)
243 centerwindow(self.fenetre)
246 self.fenetre.title(titre)
247 self.but_save.configure(text="Ajouter",command=self.traite_selection)
248 # séparateur par défaut
249 self.separateur = ';'
250 # création de la zone de saisie du séparateur
251 l_separateurs_autorises = self.get_separateurs_autorises()
252 self.choix_sep = Pmw.ComboBox(self.frame_boutons,
253 label_text = "Séparateur :",
256 selectioncommand = self.choose_separateur,
257 scrolledlist_items = l_separateurs_autorises)
258 self.choix_sep.component('entry').configure(width=6)
259 self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')
260 self.choix_sep.selectitem(self.separateur)
262 self.but_quit.place_forget()
263 self.but_save.place_forget()
264 self.but_all = Button(self.frame_boutons,text = "Tout Sélectionner", command=self.tout)
265 self.but_save.place(relx=0.6,rely=0.6,anchor='center')
266 self.but_quit.place(relx=0.8,rely=0.6,anchor='center')
267 self.but_all.place(relx=0.7,rely=0.2,anchor='center')
268 self.choose_separateur('espace')
271 def get_separateurs_autorises(self):
273 Retourne la liste des séparateurs autorisés
275 return ['espace',';',',']
277 def choose_separateur(self,nom_sep):
279 Affecte à self.separateur le caractère séparateur correspondant à nom_sep
281 if nom_sep == 'espace' :
282 self.separateur = ' '
284 self.separateur = nom_sep
288 texte=self.texte.splitlines()
290 for mot in string.split(l,self.separateur):
291 if mot != '' and mot != ' ' and mot != self.separateur :
293 self.traite_selection(liste)
295 def traite_selection(self,liste=None):
296 """ Cette méthode effectue tous les traitements nécessaires pour vérifier
297 et affecter la liste de valeurs à l'objet réprésenté par self.item
299 # Récupère la liste des chaines de caractères de la zone sélectionnée
302 message,liste = self.recupere_liste()
303 if self.test_probleme(message,"Sélectionnez des données") == 0:
305 # Vérifie que le nombre de données est dans les limites attendues
306 message = self.verif_liste(liste)
307 if self.test_probleme(message,"Vérifiez le nombre de données") == 0:
309 # Crée une liste de valeurs du type attendu
310 message,liste_valeurs = self.creation_liste_valeurs(liste)
311 if self.test_probleme(message,"Vérifiez le type des données") == 0:
313 # Vérifie que chaque valeur est dans le domaine exigé
314 message = self.verif_valeurs(liste_valeurs)
315 if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:
317 # Ajoute les valeurs dans la liste de valeurs du mot-clé
318 if self.cardinal != 1 :
322 if (len(liste_valeurs)%nb != 0):
323 message="La cardinalité n'est pas correcte"
324 self.test_probleme(message,"On attend des tuples")
326 for i in range(len(liste_valeurs)/nb) :
328 t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1])
330 t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1], liste_valeurs[i*nb+2])
332 print "probleme : prevenir la maintenance Eficas"
335 liste_valeurs=l_valeurs
336 self.ajouter_valeurs(liste_valeurs)
337 self.appli.affiche_infos("Liste de valeurs acceptée")
339 def test_probleme(self, message, message_eficas):
340 """ Cette méthode affiche un message d'erreur si message != ''
341 et retourne 0, sinon retourne 1 sans rien afficher.
344 showinfo("Problème",message,parent=self.fenetre)
345 self.fenetre.tkraise()
346 self.appli.affiche_infos(message_eficas)
351 def recupere_liste(self):
352 """ Cette méthode récupère le texte de la zone sélectionnée, construit et
353 retourne une liste avec les chaines qui se trouvent entre les séparateurs.
354 S'il n'y a pas de données selectionnées, elle retourne un message d'erreur
359 selection=self.fenetre.selection_get()
361 message = "Pas de donnée sélectionnée"
363 # les retours chariots doivent être interprétés comme des séparateurs
364 selection = string.replace(selection,'\n',self.separateur)
365 # on splitte la sélection suivant le caractère séparateur
366 liste_chaines = string.split(selection,self.separateur)
368 for chaine in liste_chaines:
369 chaine = string.strip(chaine)
370 if chaine != '' : l_chaines.append(chaine)
371 return message,l_chaines
373 def verif_liste(self, liste):
374 """ Cette méthode effectue des tests sur le nombre d'éléments de la liste
375 et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur
379 # nombre d'éléments sélectionnés
380 nombre_elements = len(liste)
381 # nombre d'éléments déja dans la liste du panel
382 nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())
383 multiplicite = self.item.GetMultiplicite()
384 if (nombre_elements % multiplicite) != 0:
385 message = "Vous devez sélectionner "+str(multiplicite)+" * n données"
387 nombre_valeurs = nombre_elements / multiplicite
388 cardinalite = self.item.GetMinMax()
389 if nombre_valeurs < cardinalite[0]:
390 message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"
392 if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):
393 message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"
398 def creation_liste_valeurs(self, liste):
399 """ Cette méthode crée et retourne une liste de valeurs du type attendu
400 par le mot-clé. La liste de valeurs est créée à partir de la liste
401 de chaines de caractères transmise.
403 type_attendu = self.item.GetType()[0]
404 if type_attendu == 'R':
405 return self.convertir(liste, f_conversion= float)
406 elif type_attendu == 'I':
407 return self.convertir(liste, f_conversion= int)
408 elif type_attendu == 'TXM':
409 return self.convertir(liste)
411 message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"
414 def convertir(self, liste, f_conversion=None):
415 """ Cette méthode essaie de convertir les éléments de la liste avec la
416 fonction f_conversion si elle existe, et retourne la liste des
417 éléments dans le type voulu en cas de succès, sinon retourne None.
424 liste_valeurs.append(f_conversion(chaine))
426 message = "Impossible de convertir "+chaine+" dans le type attendu"
429 liste_valeurs.append(chaine)
430 return message,liste_valeurs
432 def verif_valeurs(self, liste_valeurs):
433 """ Cette méthode teste la validité de tous les éléments de la liste,
434 retourne un message vide s'ils sont valides
435 ou un message non vide au premier élément non valide rencontré
438 for valeur in liste_valeurs:
439 test,message = self.item.object.verif_type(valeur)
440 if test == 0: return message
443 def ajouter_valeurs(self, liste_valeurs):
444 """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""
445 liste = self.panel.Liste_valeurs.get_liste()
446 liste.extend(liste_valeurs)
447 self.panel.Liste_valeurs.put_liste(liste)
449 class FenetreDeParametre(Fenetre) :
450 def __init__(self,parent,item,appli,texte):
453 self.fenetre = Toplevel()
454 self.fenetre.configure(width = 250,height=100)
455 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
456 self.fenetre.title("Parametres")
457 self.titre = "Parametres"
458 self.texte = string.replace(texte,'\r\n','\n')
459 fonte=fontes.standardcourier10
461 # définition des frames
462 self.frame_texte = Frame(self.fenetre)
463 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.7)
464 # définition de la zone texte et du scrollbar
465 self.zone_texte = Text(self.frame_texte,font=fonte)
466 self.zone_texte.bind("<Key-Prior>", self.page_up)
467 self.zone_texte.bind("<Key-Next>", self.page_down)
468 self.zone_texte.bind("<Key-Up>", self.unit_up)
469 self.zone_texte.bind("<Key-Down>", self.unit_down)
470 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
471 self.scroll_v.pack(side='right',fill ='y')
472 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
473 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
475 self.affiche_texte(self.texte)
476 self.zone_texte.config(state="disabled")
478 # définition des boutons
479 self.frame_boutons = Frame(self.fenetre)
480 self.frame_boutons.place(relheight=0.3,relx=0,rely=0.65,relwidth=1.)
481 self.label1 = Label(self.frame_boutons,text="surligner la")
482 self.label2 = Label(self.frame_boutons,text="ligne entière")
483 self.label1.place(relx=0.1,rely=0)
484 self.label2.place(relx=0.1,rely=0.5)
485 self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
486 self.but_save = Button(self.frame_boutons,text = "Choisir",command = self.Choisir)
487 self.but_save.place(relx=0.6,rely=0,relheight=1)
488 self.but_quit.place(relx=0.8,rely=0,relheight=1)
493 selection=self.zone_texte.selection_get()
495 showerror("Pas de donnée sélectionnée",
496 "Selectionner un parametre")
498 for param in selection.splitlines():
499 nomparam=param[0:param.find("=")-1]
501 l_param=l_param+nomparam+','
502 self.parent.entry.delete(0,Tkinter.END)
503 self.parent.entry.insert(0,l_param[0:-1])
504 self.parent.valid_valeur()
509 Cette classe permet de créer une boîte Dialog dans laquelle
510 on affiche un formulaire à remplir par l'utilisateur
512 def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):
514 if items in ((),[]) : return
518 self.fen_pere = fen_pere
519 self.obj_pere = obj_pere
521 self.command = commande
525 self.init_validateurs()
528 self.init_items_formulaire()
529 self.fenetre.activate(geometry='centerscreenalways')
531 def init_validateurs(self):
533 Crée le dictionnaire des validateurs des objets reconnus par le formulaire
535 self.d_validateurs = {}
536 self.d_validateurs['rep'] = self.repvalidator
537 self.d_validateurs['file'] = self.filevalidator
538 self.d_validateurs['cata']= self.catavalidator
539 self.d_validateurs['mot']= self.motvalidator
540 self.d_validateurs['mot2']= self.mot2validator
541 self.d_validateurs['mot3']= self.mot3validator
542 self.d_validateurs['mot4']= self.mot4validator
544 def init_fenetre(self):
546 Crée la fenêtre Dialog
548 if self.mode == 'query':
549 buttons=('Valider','Annuler')
550 defaultbutton = 'Valider'
551 elif self.mode == 'display':
553 buttons=(self.command[0],'OK')
558 self.fenetre = Pmw.Dialog(self.fen_pere,
560 defaultbutton = defaultbutton,
562 command = self.execute)
563 self.fenetre.withdraw()
565 def init_texte(self):
567 Crée le label qui affiche le texte à l'intérieur du panneau
569 fonte=fontes.standard
570 fr_texte = Frame(self.fenetre.interior(),height=60)
571 fr_texte.pack(side='top',fill='x',expand=1)
572 Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
574 def init_items_formulaire(self):
576 Crée et affiche les items dans la boîte de dialogue
580 self.item_widgets = {}
582 for item in self.items:
583 if len(item[0])>length_maxi : length_maxi = len(item[0])
584 window = self.fenetre.interior()
585 for item in self.items :
587 label,nature,nom_var,defaut = item
591 label,nature,nom_var,defaut,chaine,chaine2 = item
593 # création de la frame
594 fr_item = Frame(window,height=40,width=700)
595 fr_item.pack(side='top',fill='x',expand=1)
597 Label(fr_item,text = label).place(relx=0.05,rely=0.4)
598 if nature in ('rep','file','cata','mot','mot2','mot3','mot4'):
599 # création de l'entry
600 e_item = Entry(fr_item)
601 e_item.place(relx=0.5,rely=0.4,relwidth=0.45)
602 self.widgets.append(e_item)
603 self.item_widgets[item] = e_item
604 if defaut : e_item.insert(0,str(defaut))
605 elif nature == 'YesNo':
606 # création de la StringVar
608 setattr(self,'item_'+nom_var,var)
610 # création du radiobouton
611 rb1 = Radiobutton(fr_item,text=chaine,variable=var,value='OUI')
612 rb2 = Radiobutton(fr_item,text=chaine2,variable=var,value='NON')
613 rb1.place(relx=0.65,rely=0.5,anchor='center')
614 rb2.place(relx=0.80,rely=0.5,anchor='center')
615 self.widgets.append((rb1,rb2))
616 self.item_widgets[item] = var
617 # détermination de la méthode à appliquer sur les boutons
618 if self.mode == 'query':
619 function = self.active
620 elif self.mode == 'display':
621 function = self.inactive
624 # on applique la méthode sur les boutons (activation ou désactivation)
625 for widget in self.widgets :
626 if type(widget) == types.TupleType:
628 apply(function,(widg,),{})
630 apply(function,(widget,),{})
632 def active(self,widget):
634 Active le widget passé en argument
636 widget.configure(state='normal',bg='white')
638 def inactive(self,widget):
640 Inactive le widget passé en argument
642 if not isinstance(widget,Radiobutton) :
643 widget.configure(state='disabled',bg='gray95')
645 widget.configure(state='disabled')
647 # --------------------------------------------------------------------------------
648 # Validateurs des noms de répertoire, de fichiers et de catalogues
649 # -------------------------------------------------------------------------------
651 def motvalidator(self,text):
653 return self.motlongueurvalidator(text2,1)
655 def mot2validator(self,text):
656 return self.motlongueurvalidator(text,2)
658 def mot3validator(self,text):
659 return self.motlongueurvalidator(text,3)
661 def mot4validator(self,text):
662 return self.motlongueurvalidator(text,4)
664 def motlongueurvalidator(self,text,longueur):
666 if ((text[0] != "(") or (text[-1] != ")")) : return 0
667 if len(text.split(",")) != longueur : return 0
672 def repvalidator(self,text):
674 Teste si text peut faire référence à un répertoire ou non
675 Retourne 1 si valide, 0 sinon
677 return os.path.isdir(text),'Répertoire introuvable : %s' %text
679 def filevalidator(self,text):
681 Teste si text peut faire référence à un fichier ou non
682 Retourne 1 si valide, 0 sinon
684 return os.path.isfile(text),'Fichier introuvable : %s' %text
686 def catavalidator(self,text):
688 Teste si text est un chemin d'accès valide à un catalogue
689 Retourne 1 si valide, 0 sinon
691 return os.path.isfile(text),"Catalogue introuvable : %s" %text
693 # --------------------------------------------------------------------------------
694 # Méthodes callbacks des boutons et de fin
695 # --------------------------------------------------------------------------------
697 def execute(self,txt):
699 Cette commande est activée à chaque clic sur un bouton.
700 Redirige l'action sur la bonne méthode en fonction du bouton activé
704 elif txt in ('OK','Annuler'):
706 elif txt == 'Modifier':
707 self.resultat = apply(self.command[1],(),{})
708 self.fenetre.destroy()
710 print "Nom de bouton inconnu"
715 Commande qui termine le panneau et sauvegarde les nouvelles options
716 dans l'objet resultat (dictionnaire)
719 for item,widget in self.item_widgets.items():
722 valeur = widget.get()
723 if self.d_validateurs.has_key(type_var):
724 test = self.d_validateurs[type_var](valeur)
726 # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode
727 # sans tuer la fenêtre bien sûr
728 widget.selection_range(0,END)
730 dico[nom_var] = valeur
731 self.fenetre.destroy()
735 self.fenetre.destroy()
739 """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
740 en passant les commandes à lancer suivant différents bindings """
741 def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre='',
742 optionReturn=None, fonte_titre=fontes.standard_gras_souligne):
751 self.selection = None
752 self.liste_commandes = liste_commandes
753 self.liste_marques = liste_marques
758 self.optionReturn = optionReturn
759 self.fonte_titre=fonte_titre
763 self.make_label_titre()
764 self.make_entry_filtre()
767 self.entry.component('entry').focus()
771 def make_label_titre(self):
772 """ Crée le label correspondant au titre """
773 if self.titre == '' : return
774 self.label = Label(self.page,
776 font = self.fonte_titre)
777 self.label.pack(side='top',pady=2)
779 def make_entry_filtre(self):
780 """ Crée l'entry permettant à l'utilisateur d'entrer un filtre de sélection dans la liste """
781 if self.filtre != 'oui' : return
782 self.entry = Pmw.EntryField(self.page,labelpos='w',
783 label_text="Filtre :",
784 command=self.entry_changed)
785 self.entry.pack(side='top',pady=2)
787 def make_text_box(self):
788 """ Crée la fenêtre texte dans laquelle sera affichée la liste """
789 self.MCbox = Text (self.page,relief='sunken',bg='gray95',bd=2)
790 self.MCscroll = Scrollbar (self.page,command = self.MCbox.yview)
791 self.MCscroll.pack(side='right',fill ='y',pady=2)
792 self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
793 self.MCbox.configure(yscrollcommand=self.MCscroll.set)
796 def affiche_liste(self):
797 """ Affiche la liste dans la fenêtre"""
799 self.MCbox.config(state=NORMAL)
800 self.MCbox.delete(1.0,END)
803 for objet in self.liste :
804 if type(objet) == types.InstanceType or isinstance(objet,object):
805 #instance ancienne mode ou nouvelle mode
810 elif type(objet) in (types.StringType,types.IntType):
812 elif type(objet) == types.FloatType :
813 mot = self.parent.get_valeur_texte(objet)
816 elif type(objet) == types.TupleType :
824 valtexte = self.parent.get_valeur_texte(val)
832 label = Label(self.MCbox,
834 fg = 'black',bg = 'gray95',justify = 'left')
835 self.dico_labels[mot]=label
836 self.dico_place[mot]=self.nBlabel
837 self.dico_mots[label]=mot
838 self.nBlabel=self.nBlabel+1
839 liste_labels.append(label)
840 self.MCbox.window_create(END,
843 self.MCbox.insert(END,'\n')
844 if self.optionReturn != None :
845 label.bind("<Return>",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c))
846 label.bind("<KP_Enter>",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c))
847 label.bind("<Key-Right>",lambda e,s=self,x=objet,l=label : s.selectNextItem(x,l))
848 label.bind("<Key-Down>",lambda e, s=self,x=objet,l=label : s.selectNextItem(x,l))
849 label.bind("<Key-Left>" ,lambda e,s=self,x=objet,l=label : s.selectPrevItem(x,l))
850 label.bind("<Key-Up>" ,lambda e,s=self,x=objet,l=label : s.selectPrevItem(x,l))
851 if self.active == 'oui':
852 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))
853 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))
854 label.bind(self.liste_commandes[2][0],lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitem(x,l,c))
856 for marque in self.liste_marques:
858 self.markitem(liste_labels[marque])
862 self.MCbox.config(state=DISABLED)
863 self.selection = None
865 for event,callback in self.liste_commandes:
866 if event == "<Enter>":
867 self.selection=None,None,callback
870 def clear_marque(self):
872 self.dico_labels[self.arg_selected].configure(bg='gray95',fg='black')
873 self.arg_selected = ''
877 def surligne(self,marque):
879 self.highlightitem(self.dico_labels[marque])
880 self.arg_selected = marque
884 def chooseitemsurligne(self,mot,label,commande):
885 """ Active la méthode de choix passée en argument"""
887 mot=self.arg_selected
889 except AsException,e:
891 showerror(raison.split('\n')[0],raison)
893 def chooseitem(self,mot,label,commande):
894 """ Active la méthode de choix passée en argument"""
897 except AsException,e:
899 showerror(raison.split('\n')[0],raison)
901 def afficheMot(self,mot):
902 """ Pour contourner le bug sur l index
903 on commence par la methode dite normale
904 puis par la methode de contournement
908 labelsuivant=self.dico_labels[mot]
909 index = self.MCbox.index(labelsuivant)
910 self.MCbox.see(index)
912 posmot=self.dico_place[mot]
913 totale=self.nBlabel + 0.0
914 self.MCbox.yview_moveto(posmot/totale)
916 def selectNextItem(self,mot,label):
917 index=self.liste.index(mot)
919 if indexsuivant > len(self.liste) -1:
921 motsuivant=self.liste[indexsuivant]
922 labelsuivant=self.dico_labels[motsuivant]
923 self.afficheMot(motsuivant)
924 self.selectthis(motsuivant,labelsuivant,self.selection[2],)
927 def selectPrevItem(self,mot,label):
928 index=self.liste.index(mot)
930 motprec=self.liste[indexprec]
931 labelprec=self.dico_labels[motprec]
932 self.afficheMot(motprec)
933 self.selectthis(motprec,labelprec,self.selection[2],)
936 def selectthis(self,mot,label,commande) :
938 if self.selection != None :
939 self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
940 self.highlightitem(label)
941 self.selection = (mot,label,commande)
942 self.arg_selected = mot
943 if commande : commande(mot)
945 def selectitem(self,mot,label,commande) :
946 """ Met l'item sélectionné (représenté par son label) en surbrillance
947 et lance la commande associée au double-clic"""
951 self.selectthis(mot,label,commande)
953 def highlightitem(self,label) :
954 """ Met l'item représenté par son label en surbrillance """
956 label.configure(bg='#00008b',fg='white')
958 def markitem(self,label):
959 """ Met l'item (représenté par son label) en rouge """
960 label.configure(bg='gray95',fg='red')
962 def deselectitem(self,label,mot='',commande=None) :
963 """ Remet l'item (représenté par son label) en noir"""
964 if label:label.configure(bg='gray95',fg='black')
965 self.arg_selected = ''
966 if commande and mot : commande(mot)
968 def cherche_selected_item(self):
970 index=self.MCbox.index(self.selection[1])
971 lign,col=map(int,string.split(index,'.'))
973 label=self.dico_labels[self.arg_selected]
974 mot=self.dico_mots[label]
975 lign=self.dico_place[mot]+1
978 def remove_selected_item(self):
980 index=self.MCbox.index(self.selection[1])
981 lign,col=map(int,string.split(index,'.'))
983 label=self.dico_labels[self.arg_selected]
984 mot=self.dico_mots[label]
985 lign=self.dico_place[mot]+1
986 del self.liste[lign-1]
989 def entry_changed(self,event=None):
990 """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
991 de l'entry et frappe <Return>"""
992 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
993 filtre = self.entry.get()+"*"
994 FILTRE = string.upper(filtre)
996 for arg in self.liste :
997 if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
998 label=self.dico_labels[arg]
1000 self.selectitem(arg,label,self.selection[2])
1004 #self.dico_labels[self.arg_selected].focus_set()
1009 # PN attention à la gestion des paramétres
1010 # cela retourne H = 1 , et ni H, ni 1
1012 # print val.__class__.__name__
1013 def get_liste(self):
1015 for val in self.liste:
1023 def put_liste(self,liste):
1025 self.affiche_liste()
1028 """ Cette classe permet d'afficher au lancement d'EFICAS le message
1029 d'attente et la barre de progression"""
1030 def __init__(self,master,message,barre ='oui'):
1031 from Tools.foztools.foztools import Slider
1032 fonte=fontes.standard12_gras
1034 self.frame = Frame(self.master)
1035 self.frame.pack(expand=1,fill='both')
1036 self.mess = Label(self.frame,text=message,justify='center',
1037 bd=2,relief='groove',font=fonte)
1038 self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
1039 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
1040 fillColor='#00008b',width=200,height=30,
1041 background='white',labelColor='red')
1043 self.progress.frame.pack(in_=self.frame,side='top')
1044 self.master.update()
1046 self.progress.frame.after(1000,self.update)
1048 def configure(self,**options):
1049 if options.has_key('message'):
1050 self.mess.configure(text=options['message'])
1051 if options.has_key('barre'):
1052 if options['barre'] == 'oui' :
1053 self.progress.frame.pack(in_=self.frame,side='top')
1054 elif options['barre'] == 'non' :
1055 self.progress.frame.pack_forget()
1056 self.master.update_idletasks()
1059 self.frame.destroy()
1060 self.master.update()
1062 def update(self,event=None):
1063 """ Permet de faire avancer la barre de progression """
1066 bar.value = bar.value+self.increment
1068 self.master.after(100,self.update)
1072 def configure_barre(self,nb):
1073 """ Calcule l'incrément de progression de la barre en fonction
1074 du nombre d'opérations à effectuer afin que le compteur
1075 soit à 100% à la fin des opérations"""
1076 self.increment = 100./nb
1077 self.progress.update()
1079 class Ask_Format_Fichier :
1081 Cette classe permet de créer une fenêtre Toplevel dans laquelle
1082 on propose le choix du format de fichier de commandes à ouvrir
1084 def __init__(self,appli):
1085 self.fenetre = Toplevel()
1086 self.fenetre.configure(width = 250,height=150)
1087 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
1088 self.fenetre.title("Choix du format du fichier de commandes")
1089 # définition des frames
1090 self.frame_texte = Frame(self.fenetre)
1091 self.frame_radioboutons = Frame(self.fenetre)
1092 self.frame_bouton_ok = Frame(self.fenetre)
1093 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
1094 self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
1095 self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
1096 # définition de la zone texte et du scrollbar
1097 zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
1098 zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
1099 # définition des radioboutons
1100 Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
1101 variable=appli.format_fichier,value='Aster').pack(anchor='n')
1102 Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
1103 variable=appli.format_fichier,value='Python').pack(anchor='n')
1104 # création du bouton OK
1105 Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
1106 # centrage de la fenêtre
1107 centerwindow(self.fenetre)
1110 self.fenetre.destroy()
1112 class BARRE_K2000(Toplevel):
1113 def __init__(self,master=None,text = ""):
1114 Toplevel.__init__(self,master,relief='groove')
1115 self.master.iconify()
1116 self.geometry("250x100+0+0")
1117 self.protocol("WM_DELETE_WINDOW",self.quit)
1118 # frame principale dans self (= Toplevel)
1119 self.frame = Frame(self)
1120 self.frame.place(relwidth=1,relheight=1)
1121 # frame contenant le texte à afficher
1122 self.frame_text = Frame(self.frame)
1123 self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
1124 # frame contenant le canvas de la barre
1125 self.frame_canv = Frame(self.frame)
1126 self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
1127 # canvas dans lequel sera affichée la barre K2000
1128 self.canvas = Canvas(self.frame_canv)
1129 self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
1130 # on affiche le texte et la barre
1131 self.build_text(text)
1133 #self.overrideredirect(1)
1134 # on active la barre ...
1135 self.master.after(1000,self.launch)
1136 # on centre la fenêtre
1140 def build_text(self,text):
1142 Affichage de text dans frame_text
1144 self.texte_var = StringVar()
1145 self.texte_var.set(text)
1146 Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
1148 def build_batons(self):
1150 Construit la suite de bâtons dans le canvas
1156 for i in range(0,40):
1157 id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
1158 self.l_batons.append(id)
1162 Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
1166 self.master.deiconify()
1168 if self.sens == 'D':
1169 self.black = self.black+1
1170 l_bat = self.l_batons[0:self.black+1]
1172 elif self.sens == 'G':
1173 self.black = self.black-1
1174 l_bat = self.l_batons[self.black:]
1178 if num_color < 10 : color = 'black'
1179 elif num_color > 90 : color = 'white'
1180 else: color = 'gray'+`num_color`
1181 self.canvas.itemconfigure(bat,fill=color)
1183 if self.black == len(self.l_batons) :
1185 if self.black == 0 and self.sens == 'G':self.sens = 'D'
1186 self.after(80,self.launch)
1188 def update_text(self,new_text):
1190 Remplace le texte affiché par new_text
1192 self.texte_var.set(new_text)
1197 class ListeChoixParGroupes(ListeChoix) :
1199 Cette classe est utilisée pour afficher une liste de commandes classées par
1200 groupes. L'utilisateur peut réaliser des actions de selection
1201 qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
1203 liste_commandes = (("<Enter>",self.selectCmd),
1204 ("<Leave>",self.deselectCmd),
1205 ("<Double-Button-1>",self.defCmd))
1206 Il s'agit d'une liste de doublets dont le premier element est un evenement et le
1207 deuxieme un callback a appeler sur l'evenement en question.
1210 def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
1211 active ='oui',filtre='non',titre='',optionReturn=None,fonte_titre=fontes.standard_gras_souligne):
1212 self.parent = parent
1214 self.liste_groupes = liste_groupes
1215 self.dict_groupes = dict_groupes
1217 self.selection = None
1218 self.liste_commandes = liste_commandes
1219 self.liste_marques = liste_marques
1220 self.arg_selected=''
1221 self.active = active
1223 self.filtre = filtre
1224 self.optionReturn = optionReturn
1225 self.fonte_titre=fonte_titre
1228 def affiche_liste(self):
1229 """ Affiche la liste dans la fenêtre"""
1232 self.MCbox.config(state=NORMAL)
1233 self.MCbox.delete(1.0,END)
1234 for grp in self.liste_groupes:
1235 # On itère sur les groupes
1236 if grp == "CACHE":continue
1237 liste_commandes=self.dict_groupes[grp]
1238 text="GROUPE<<<<<<<< "+grp+" "
1239 text=text+">"*max(0,30-len(text))
1240 label = Label(self.MCbox,
1242 fg = 'black',bg = 'gray95',justify = 'left')
1243 # On stocke la relation entre le nom de la commande et le label
1244 self.dico_labels[grp]=label
1245 liste_labels.append(label)
1246 self.MCbox.window_create(END,
1249 self.MCbox.insert(END,'\n')
1250 for cmd in liste_commandes:
1251 label = Label(self.MCbox,
1253 fg = 'black',bg = 'gray95',justify = 'left')
1254 # On stocke la relation entre le nom de la commande et le label
1255 self.dico_labels[cmd]=label
1256 self.dico_mots[label]=cmd
1257 self.MCbox.window_create(END,
1260 self.MCbox.insert(END,'\n')
1262 def null(*tp,**args): return
1264 if self.active == 'oui':
1265 # Traitement par defaut des evenements
1266 label.bind("<Enter>",lambda e,s=self,c=null,x=cmd,l=label: s.selectitem(x,l,c))
1267 label.bind("<Leave>",lambda e,s=self,c=null,x=cmd,l=label: s.deselectitem(l,x,c))
1268 label.bind("<Double-Button-1>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
1269 label.bind("<Return>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
1270 label.bind("<KP_Enter>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
1271 label.bind("<Key-Right>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectNextItem(x,l,c,gr,x))
1272 label.bind("<Key-Down>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectNextItem(x,l,c,gr,x))
1273 label.bind("<Key-Left>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectPrevItem(x,l,c,gr,x))
1274 label.bind("<Key-Up>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectPrevItem(x,l,c,gr,x))
1276 # Si des callbacks sont definis on les utilise
1277 for event,callback in self.liste_commandes:
1278 if event == "<Enter>":
1279 label.bind("<Enter>",lambda e,s=self,c=callback,x=cmd,l=label: s.selectitem(x,l,c))
1280 elif event == "<Leave>":
1281 label.bind("<Leave>",lambda e,s=self,c=callback,x=cmd,l=label: s.deselectitem(l,x,c))
1282 elif event == "<Double-Button-1>":
1283 label.bind("<Double-Button-1>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
1284 elif event == "<Return>":
1285 label.bind("<Return>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
1286 elif event == "<KP_Enter>":
1287 label.bind("<KP_Enter>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
1288 elif event == "<Key-Right>":
1289 label.bind("<Key-Right>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectNextItem(x,l,c,gr,x))
1290 elif event == "<Key-Down>":
1291 label.bind("<Key-Down>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectNextItem(x,l,c,gr,x))
1292 elif event == "<Key-Left>":
1293 label.bind("<Key-Left>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectPrevItem(x,l,c,gr,x))
1294 elif event == "<Key-Up>":
1295 label.bind("<Key-Up>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectPrevItem(x,l,c,gr,x))
1297 label.bind(event,lambda e,s=self,c=callback,x=cmd,l=label: c())
1299 for marque in self.liste_marques:
1301 self.markitem(liste_labels[marque])
1305 self.MCbox.config(state=DISABLED)
1306 self.selection = None
1308 for event,callback in self.liste_commandes:
1309 if event == "<Enter>":
1310 self.selection=None,None,callback
1313 def selectPrevItem(self,mot,label,callback,group,cmd):
1314 g=self.liste_groupes.index(group)
1315 liste_commandes=self.dict_groupes[group]
1316 c=liste_commandes.index(cmd)
1318 co=liste_commandes[c-1]
1320 # debut de liste. On passe au groupe precedent
1322 gr=self.liste_groupes[g-1]
1323 co=self.dict_groupes[gr][-1]
1325 # debut des groupes. On ne fait rien
1327 # On a trouve l'item precedent
1328 labelsuivant=self.dico_labels[co]
1329 index = self.MCbox.index(labelsuivant)
1330 self.MCbox.see(index)
1331 self.selectthis(co,labelsuivant,self.selection[2],)
1334 def selectNextItem(self,mot,label,callback,group,cmd):
1335 g=self.liste_groupes.index(group)
1336 liste_commandes=self.dict_groupes[group]
1337 c=liste_commandes.index(cmd)
1339 co=liste_commandes[c+1]
1341 # fin de liste. On passe au groupe suivant
1343 gr=self.liste_groupes[g+1]
1344 co=self.dict_groupes[gr][0]
1346 # fin des groupes. On ne fait rien
1348 # On a trouve l'item suivant
1349 labelsuivant=self.dico_labels[co]
1350 index = self.MCbox.index(labelsuivant)
1351 self.MCbox.see(index)
1352 self.selectthis(co,labelsuivant,self.selection[2],)
1355 def entry_changed(self,event=None):
1357 Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
1358 de l'entry et frappe <Return>
1360 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
1362 filtre = self.entry.get()+"*"
1363 FILTRE = string.upper(filtre)
1365 # On cherche d'abord dans les noms de groupe
1366 # puis dans les noms de commande groupe par groupe
1368 for grp in self.liste_groupes:
1369 if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
1370 cmd=self.dict_groupes[grp][0]
1371 label=self.dico_labels[cmd]
1372 index = self.MCbox.index(label)
1373 self.MCbox.see(index)
1374 self.selectitem(cmd,label,self.selection[2])
1375 # On a trouve un groupe on arrete la recherche
1378 for grp in self.liste_groupes:
1379 for cmd in self.dict_groupes[grp] :
1380 if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
1381 label=self.dico_labels[cmd]
1382 index = self.MCbox.index(label)
1383 self.MCbox.see(index)
1384 self.selectitem(cmd,label,self.selection[2])
1385 # On a trouve une commande on arrete la recherche