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 Editeur.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:
809 elif type(objet) in (types.StringType,types.IntType):
811 elif type(objet) == types.FloatType :
812 mot = self.parent.get_valeur_texte(objet)
815 elif type(objet) == types.TupleType :
823 valtexte = self.parent.get_valeur_texte(val)
829 elif string.find(str(type(objet)),".SD.") :
833 label = Label(self.MCbox,
835 fg = 'black',bg = 'gray95',justify = 'left')
836 self.dico_labels[mot]=label
837 self.dico_place[mot]=self.nBlabel
838 self.dico_mots[label]=mot
839 self.nBlabel=self.nBlabel+1
840 liste_labels.append(label)
841 self.MCbox.window_create(END,
844 self.MCbox.insert(END,'\n')
845 if self.optionReturn != None :
846 label.bind("<Return>",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c))
847 label.bind("<KP_Enter>",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c))
848 label.bind("<Key-Right>",lambda e,s=self,x=objet,l=label : s.selectNextItem(x,l))
849 label.bind("<Key-Down>",lambda e, s=self,x=objet,l=label : s.selectNextItem(x,l))
850 label.bind("<Key-Left>" ,lambda e,s=self,x=objet,l=label : s.selectPrevItem(x,l))
851 label.bind("<Key-Up>" ,lambda e,s=self,x=objet,l=label : s.selectPrevItem(x,l))
852 if self.active == 'oui':
853 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))
854 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))
855 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))
857 for marque in self.liste_marques:
859 self.markitem(liste_labels[marque])
863 self.MCbox.config(state=DISABLED)
864 self.selection = None
866 for event,callback in self.liste_commandes:
867 if event == "<Enter>":
868 self.selection=None,None,callback
871 def clear_marque(self):
873 self.dico_labels[self.arg_selected].configure(bg='gray95',fg='black')
874 self.arg_selected = ''
878 def surligne(self,marque):
880 self.highlightitem(self.dico_labels[marque])
881 self.arg_selected = marque
885 def chooseitemsurligne(self,mot,label,commande):
886 """ Active la méthode de choix passée en argument"""
888 mot=self.arg_selected
890 except AsException,e:
892 showerror(raison.split('\n')[0],raison)
894 def chooseitem(self,mot,label,commande):
895 """ Active la méthode de choix passée en argument"""
898 except AsException,e:
900 showerror(raison.split('\n')[0],raison)
902 def afficheMot(self,mot):
903 """ Pour contourner le bug sur l index
904 on commence par la methode dite normale
905 puis par la methode de contournement
909 labelsuivant=self.dico_labels[mot]
910 index = self.MCbox.index(labelsuivant)
911 self.MCbox.see(index)
913 posmot=self.dico_place[mot]
914 totale=self.nBlabel + 0.0
915 self.MCbox.yview_moveto(posmot/totale)
917 def selectNextItem(self,mot,label):
918 index=self.liste.index(mot)
920 if indexsuivant > len(self.liste) -1:
922 motsuivant=self.liste[indexsuivant]
923 labelsuivant=self.dico_labels[motsuivant]
924 self.afficheMot(motsuivant)
925 self.selectthis(motsuivant,labelsuivant,self.selection[2],)
928 def selectPrevItem(self,mot,label):
929 index=self.liste.index(mot)
931 motprec=self.liste[indexprec]
932 labelprec=self.dico_labels[motprec]
933 self.afficheMot(motprec)
934 self.selectthis(motprec,labelprec,self.selection[2],)
937 def selectthis(self,mot,label,commande) :
939 if self.selection != None :
940 self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
941 self.highlightitem(label)
942 self.selection = (mot,label,commande)
943 self.arg_selected = mot
944 if commande : commande(mot)
946 def selectitem(self,mot,label,commande) :
947 """ Met l'item sélectionné (représenté par son label) en surbrillance
948 et lance la commande associée au double-clic"""
952 self.selectthis(mot,label,commande)
954 def highlightitem(self,label) :
955 """ Met l'item représenté par son label en surbrillance """
957 label.configure(bg='#00008b',fg='white')
959 def markitem(self,label):
960 """ Met l'item (représenté par son label) en rouge """
961 label.configure(bg='gray95',fg='red')
963 def deselectitem(self,label,mot='',commande=None) :
964 """ Remet l'item (représenté par son label) en noir"""
965 if label:label.configure(bg='gray95',fg='black')
966 self.arg_selected = ''
967 if commande and mot : commande(mot)
969 def cherche_selected_item(self):
971 index=self.MCbox.index(self.selection[1])
972 lign,col=map(int,string.split(index,'.'))
974 label=self.dico_labels[self.arg_selected]
975 mot=self.dico_mots[label]
976 lign=self.dico_place[mot]+1
979 def remove_selected_item(self):
981 index=self.MCbox.index(self.selection[1])
982 lign,col=map(int,string.split(index,'.'))
984 label=self.dico_labels[self.arg_selected]
985 mot=self.dico_mots[label]
986 lign=self.dico_place[mot]+1
987 del self.liste[lign-1]
990 def entry_changed(self,event=None):
991 """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
992 de l'entry et frappe <Return>"""
993 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
994 filtre = self.entry.get()+"*"
995 FILTRE = string.upper(filtre)
997 for arg in self.liste :
998 if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
999 label=self.dico_labels[arg]
1000 self.afficheMot(arg)
1001 self.selectitem(arg,label,self.selection[2])
1005 #self.dico_labels[self.arg_selected].focus_set()
1010 # PN attention à la gestion des paramétres
1011 # cela retourne H = 1 , et ni H, ni 1
1013 # print val.__class__.__name__
1014 def get_liste(self):
1016 for val in self.liste:
1024 def put_liste(self,liste):
1026 self.affiche_liste()
1029 """ Cette classe permet d'afficher au lancement d'EFICAS le message
1030 d'attente et la barre de progression"""
1031 def __init__(self,master,message,barre ='oui'):
1032 from Tools.foztools.foztools import Slider
1033 fonte=fontes.standard12_gras
1035 self.frame = Frame(self.master)
1036 self.frame.pack(expand=1,fill='both')
1037 self.mess = Label(self.frame,text=message,justify='center',
1038 bd=2,relief='groove',font=fonte)
1039 self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
1040 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
1041 fillColor='#00008b',width=200,height=30,
1042 background='white',labelColor='red')
1044 self.progress.frame.pack(in_=self.frame,side='top')
1045 self.master.update()
1047 self.progress.frame.after(1000,self.update)
1049 def configure(self,**options):
1050 if options.has_key('message'):
1051 self.mess.configure(text=options['message'])
1052 if options.has_key('barre'):
1053 if options['barre'] == 'oui' :
1054 self.progress.frame.pack(in_=self.frame,side='top')
1055 elif options['barre'] == 'non' :
1056 self.progress.frame.pack_forget()
1057 self.master.update_idletasks()
1060 self.frame.destroy()
1061 self.master.update()
1063 def update(self,event=None):
1064 """ Permet de faire avancer la barre de progression """
1067 bar.value = bar.value+self.increment
1069 self.master.after(100,self.update)
1073 def configure_barre(self,nb):
1074 """ Calcule l'incrément de progression de la barre en fonction
1075 du nombre d'opérations à effectuer afin que le compteur
1076 soit à 100% à la fin des opérations"""
1077 self.increment = 100./nb
1078 self.progress.update()
1080 class Ask_Format_Fichier :
1082 Cette classe permet de créer une fenêtre Toplevel dans laquelle
1083 on propose le choix du format de fichier de commandes à ouvrir
1085 def __init__(self,appli):
1086 self.fenetre = Toplevel()
1087 self.fenetre.configure(width = 250,height=150)
1088 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
1089 self.fenetre.title("Choix du format du fichier de commandes")
1090 # définition des frames
1091 self.frame_texte = Frame(self.fenetre)
1092 self.frame_radioboutons = Frame(self.fenetre)
1093 self.frame_bouton_ok = Frame(self.fenetre)
1094 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
1095 self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
1096 self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
1097 # définition de la zone texte et du scrollbar
1098 zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
1099 zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
1100 # définition des radioboutons
1101 Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
1102 variable=appli.format_fichier,value='Aster').pack(anchor='n')
1103 Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
1104 variable=appli.format_fichier,value='Python').pack(anchor='n')
1105 # création du bouton OK
1106 Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
1107 # centrage de la fenêtre
1108 centerwindow(self.fenetre)
1111 self.fenetre.destroy()
1113 class BARRE_K2000(Toplevel):
1114 def __init__(self,master=None,text = ""):
1115 Toplevel.__init__(self,master,relief='groove')
1116 self.master.iconify()
1117 self.geometry("250x100+0+0")
1118 self.protocol("WM_DELETE_WINDOW",self.quit)
1119 # frame principale dans self (= Toplevel)
1120 self.frame = Frame(self)
1121 self.frame.place(relwidth=1,relheight=1)
1122 # frame contenant le texte à afficher
1123 self.frame_text = Frame(self.frame)
1124 self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
1125 # frame contenant le canvas de la barre
1126 self.frame_canv = Frame(self.frame)
1127 self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
1128 # canvas dans lequel sera affichée la barre K2000
1129 self.canvas = Canvas(self.frame_canv)
1130 self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
1131 # on affiche le texte et la barre
1132 self.build_text(text)
1134 #self.overrideredirect(1)
1135 # on active la barre ...
1136 self.master.after(1000,self.launch)
1137 # on centre la fenêtre
1141 def build_text(self,text):
1143 Affichage de text dans frame_text
1145 self.texte_var = StringVar()
1146 self.texte_var.set(text)
1147 Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
1149 def build_batons(self):
1151 Construit la suite de bâtons dans le canvas
1157 for i in range(0,40):
1158 id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
1159 self.l_batons.append(id)
1163 Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
1167 self.master.deiconify()
1169 if self.sens == 'D':
1170 self.black = self.black+1
1171 l_bat = self.l_batons[0:self.black+1]
1173 elif self.sens == 'G':
1174 self.black = self.black-1
1175 l_bat = self.l_batons[self.black:]
1179 if num_color < 10 : color = 'black'
1180 elif num_color > 90 : color = 'white'
1181 else: color = 'gray'+`num_color`
1182 self.canvas.itemconfigure(bat,fill=color)
1184 if self.black == len(self.l_batons) :
1186 if self.black == 0 and self.sens == 'G':self.sens = 'D'
1187 self.after(80,self.launch)
1189 def update_text(self,new_text):
1191 Remplace le texte affiché par new_text
1193 self.texte_var.set(new_text)
1198 class ListeChoixParGroupes(ListeChoix) :
1200 Cette classe est utilisée pour afficher une liste de commandes classées par
1201 groupes. L'utilisateur peut réaliser des actions de selection
1202 qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
1204 liste_commandes = (("<Enter>",self.selectCmd),
1205 ("<Leave>",self.deselectCmd),
1206 ("<Double-Button-1>",self.defCmd))
1207 Il s'agit d'une liste de doublets dont le premier element est un evenement et le
1208 deuxieme un callback a appeler sur l'evenement en question.
1211 def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
1212 active ='oui',filtre='non',titre='',optionReturn=None,fonte_titre=fontes.standard_gras_souligne):
1213 self.parent = parent
1215 self.liste_groupes = liste_groupes
1216 self.dict_groupes = dict_groupes
1218 self.selection = None
1219 self.liste_commandes = liste_commandes
1220 self.liste_marques = liste_marques
1221 self.arg_selected=''
1222 self.active = active
1224 self.filtre = filtre
1225 self.optionReturn = optionReturn
1226 self.fonte_titre=fonte_titre
1229 def affiche_liste(self):
1230 """ Affiche la liste dans la fenêtre"""
1233 self.MCbox.config(state=NORMAL)
1234 self.MCbox.delete(1.0,END)
1235 for grp in self.liste_groupes:
1236 # On itère sur les groupes
1237 if grp == "CACHE":continue
1238 liste_commandes=self.dict_groupes[grp]
1239 text="GROUPE<<<<<<<< "+grp+" "
1240 text=text+">"*max(0,30-len(text))
1241 label = Label(self.MCbox,
1243 fg = 'black',bg = 'gray95',justify = 'left')
1244 # On stocke la relation entre le nom de la commande et le label
1245 self.dico_labels[grp]=label
1246 liste_labels.append(label)
1247 self.MCbox.window_create(END,
1250 self.MCbox.insert(END,'\n')
1251 for cmd in liste_commandes:
1252 label = Label(self.MCbox,
1254 fg = 'black',bg = 'gray95',justify = 'left')
1255 # On stocke la relation entre le nom de la commande et le label
1256 self.dico_labels[cmd]=label
1257 self.dico_mots[label]=cmd
1258 self.MCbox.window_create(END,
1261 self.MCbox.insert(END,'\n')
1263 def null(*tp,**args): return
1265 if self.active == 'oui':
1266 # Traitement par defaut des evenements
1267 label.bind("<Enter>",lambda e,s=self,c=null,x=cmd,l=label: s.selectitem(x,l,c))
1268 label.bind("<Leave>",lambda e,s=self,c=null,x=cmd,l=label: s.deselectitem(l,x,c))
1269 label.bind("<Double-Button-1>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
1270 label.bind("<Return>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
1271 label.bind("<KP_Enter>",lambda e,s=self,c=null,x=cmd,l=label: s.chooseitem(x,l,c))
1272 label.bind("<Key-Right>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectNextItem(x,l,c,gr,x))
1273 label.bind("<Key-Down>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectNextItem(x,l,c,gr,x))
1274 label.bind("<Key-Left>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectPrevItem(x,l,c,gr,x))
1275 label.bind("<Key-Up>",lambda e,s=self,c=null,x=cmd,l=label,gr=grp: s.selectPrevItem(x,l,c,gr,x))
1277 # Si des callbacks sont definis on les utilise
1278 for event,callback in self.liste_commandes:
1279 if event == "<Enter>":
1280 label.bind("<Enter>",lambda e,s=self,c=callback,x=cmd,l=label: s.selectitem(x,l,c))
1281 elif event == "<Leave>":
1282 label.bind("<Leave>",lambda e,s=self,c=callback,x=cmd,l=label: s.deselectitem(l,x,c))
1283 elif event == "<Double-Button-1>":
1284 label.bind("<Double-Button-1>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
1285 elif event == "<Return>":
1286 label.bind("<Return>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
1287 elif event == "<KP_Enter>":
1288 label.bind("<KP_Enter>",lambda e,s=self,c=callback,x=cmd,l=label: s.chooseitem(x,l,c))
1289 elif event == "<Key-Right>":
1290 label.bind("<Key-Right>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectNextItem(x,l,c,gr,x))
1291 elif event == "<Key-Down>":
1292 label.bind("<Key-Down>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectNextItem(x,l,c,gr,x))
1293 elif event == "<Key-Left>":
1294 label.bind("<Key-Left>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectPrevItem(x,l,c,gr,x))
1295 elif event == "<Key-Up>":
1296 label.bind("<Key-Up>",lambda e,s=self,c=callback,x=cmd,l=label,gr=grp:s.selectPrevItem(x,l,c,gr,x))
1298 label.bind(event,lambda e,s=self,c=callback,x=cmd,l=label: c())
1300 for marque in self.liste_marques:
1302 self.markitem(liste_labels[marque])
1306 self.MCbox.config(state=DISABLED)
1307 self.selection = None
1309 for event,callback in self.liste_commandes:
1310 if event == "<Enter>":
1311 self.selection=None,None,callback
1314 def selectPrevItem(self,mot,label,callback,group,cmd):
1315 g=self.liste_groupes.index(group)
1316 liste_commandes=self.dict_groupes[group]
1317 c=liste_commandes.index(cmd)
1319 co=liste_commandes[c-1]
1321 # debut de liste. On passe au groupe precedent
1323 gr=self.liste_groupes[g-1]
1324 co=self.dict_groupes[gr][-1]
1326 # debut des groupes. On ne fait rien
1328 # On a trouve l'item precedent
1329 labelsuivant=self.dico_labels[co]
1330 index = self.MCbox.index(labelsuivant)
1331 self.MCbox.see(index)
1332 self.selectthis(co,labelsuivant,self.selection[2],)
1335 def selectNextItem(self,mot,label,callback,group,cmd):
1336 g=self.liste_groupes.index(group)
1337 liste_commandes=self.dict_groupes[group]
1338 c=liste_commandes.index(cmd)
1340 co=liste_commandes[c+1]
1342 # fin de liste. On passe au groupe suivant
1344 gr=self.liste_groupes[g+1]
1345 co=self.dict_groupes[gr][0]
1347 # fin des groupes. On ne fait rien
1349 # On a trouve l'item suivant
1350 labelsuivant=self.dico_labels[co]
1351 index = self.MCbox.index(labelsuivant)
1352 self.MCbox.see(index)
1353 self.selectthis(co,labelsuivant,self.selection[2],)
1356 def entry_changed(self,event=None):
1358 Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
1359 de l'entry et frappe <Return>
1361 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
1363 filtre = self.entry.get()+"*"
1364 FILTRE = string.upper(filtre)
1366 # On cherche d'abord dans les noms de groupe
1367 # puis dans les noms de commande groupe par groupe
1369 for grp in self.liste_groupes:
1370 if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
1371 cmd=self.dict_groupes[grp][0]
1372 label=self.dico_labels[cmd]
1373 index = self.MCbox.index(label)
1374 self.MCbox.see(index)
1375 self.selectitem(cmd,label,self.selection[2])
1376 # On a trouve un groupe on arrete la recherche
1379 for grp in self.liste_groupes:
1380 for cmd in self.dict_groupes[grp] :
1381 if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
1382 label=self.dico_labels[cmd]
1383 index = self.MCbox.index(label)
1384 self.MCbox.see(index)
1385 self.selectitem(cmd,label,self.selection[2])
1386 # On a trouve une commande on arrete la recherche