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
31 from tkFileDialog import *
32 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
36 from utils import save_in_file
37 from centerwindow import centerwindow
39 from Noyau.N_utils import repr_float
40 from Accas import AsException
42 # Surcharge de la fonction askyesno qui retourne un resultat errone en Python 2.3 avec Tk 8.4
43 # et Tkinter.wantobject==1
45 def askyesno(title=None, message=None, **options):
46 "Ask a question; return true if the answer is yes"
47 s = tkMessageBox._show(title, message, tkMessageBox.QUESTION, tkMessageBox.YESNO, **options)
48 if s == tkMessageBox.YES:return 1
49 if s == tkMessageBox.NO:return 0
55 """ Cette classe permet de créer une fenêtre Toplevel dans laquelle
56 on peut afficher un texte et qui permet de le sauver"""
57 def __init__(self,appli,titre="",texte=""):
59 self.fenetre = Toplevel()
60 self.fenetre.configure(width = 800,height=500)
61 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
62 self.fenetre.title("Visualisation du "+titre)
63 self.texte = string.replace(texte,'\r\n','\n')
65 fonte=fontes.standardcourier10
66 # définition des frames
67 self.frame_texte = Frame(self.fenetre)
68 self.frame_boutons = Frame(self.fenetre)
69 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.9)
70 self.frame_boutons.place(relheight=0.1,relx=0,rely=0.9,relwidth=1.)
71 # définition de la zone texte et du scrollbar
72 self.zone_texte = Text(self.frame_texte,font=fonte)
73 self.zone_texte.bind("<Key-Prior>", self.page_up)
74 self.zone_texte.bind("<Key-Next>", self.page_down)
75 self.zone_texte.bind("<Key-Up>", self.unit_up)
76 self.zone_texte.bind("<Key-Down>", self.unit_down)
77 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
78 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
79 self.scroll_v.pack(side='right',fill ='y')
80 #self.scroll_h.pack(side='bottom',fill ='x')
81 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
82 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
83 # définition des boutons
84 self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
85 self.but_save = Button(self.frame_boutons,text = "sauver",command = self.save)
86 self.but_quit.place(relx=0.4,rely=0.5,anchor='center')
87 self.but_save.place(relx=0.6,rely=0.5,anchor='center')
89 self.affiche_texte(self.texte)
90 centerwindow(self.fenetre)
92 def page_up(self,event):
93 event.widget.yview_scroll(-1, "page")
94 def page_down(self,event):
95 event.widget.yview_scroll(1, "page")
96 def unit_up(self,event):
97 event.widget.yview_scroll(-1, "unit")
98 def unit_down(self,event):
99 event.widget.yview_scroll(1, "unit")
102 self.fenetre.grab_set()
103 self.zone_texte.focus_set()
104 self.fenetre.wait_window(self.fenetre)
107 self.fenetre.destroy()
109 def efface_scroll(self):
110 """ Efface le scroll lorsqu'il n'est pas nécessaire : ne marche pas"""
111 self.scroll_v.pack_forget()
112 #self.scroll_h.pack_forget()
114 def affiche_texte(self,texte):
115 """ Affiche le texte dans la fenêtre """
117 self.zone_texte.insert(END,texte)
119 self.fenetre.update_idletasks()
120 x0,y0,x1,y1 = self.zone_texte.bbox(END)
121 if (y1-y0) < 300 : self.efface_scroll()
126 """ Permet de sauvegarder le texte dans un fichier dont on a demandé le nom
128 file = asksaveasfilename(defaultextension = '.comm',
129 #initialdir = self.appli.CONFIGURATION.rep_user,
130 initialdir = self.appli.CONFIGURATION.initialdir,
131 title="Sauvegarde du "+self.titre)
133 if not save_in_file(file,self.texte) :
134 showerror("Sauvegarde impossible",
135 "Impossible de sauvegarder le texte dans le fichier spécifié\n"+
136 "Vérifiez les droits d'écriture")
138 showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file)
140 class FenetreYesNo(Fenetre):
141 def __init__(self,appli,titre="",texte="",yes="Yes",no="No"):
143 self.fenetre = Toplevel()
144 self.fenetre.configure(width = 800,height=500)
145 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
146 self.fenetre.title(titre)
147 self.texte = string.replace(texte,'\r\n','\n')
149 fonte=fontes.standardcourier10
150 # définition des frames
151 self.frame_texte = Frame(self.fenetre)
152 self.frame_boutons = Frame(self.fenetre)
153 self.frame_boutons.place(relx=0,rely=0, relwidth=1.,relheight=0.1)
154 self.frame_texte.place( relx=0,rely=0.1, relwidth=1, relheight=0.9)
155 # définition de la zone texte et du scrollbar
156 self.zone_texte = Text(self.frame_texte,font=fonte)
157 self.zone_texte.bind("<Key-Prior>", self.page_up)
158 self.zone_texte.bind("<Key-Next>", self.page_down)
159 self.zone_texte.bind("<Key-Up>", self.unit_up)
160 self.zone_texte.bind("<Key-Down>", self.unit_down)
161 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
162 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
163 self.scroll_v.pack(side='right',fill ='y')
164 #self.scroll_h.pack(side='bottom',fill ='x')
165 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
166 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
167 # définition des boutons
168 self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes)
169 self.but_no = Button(self.frame_boutons,text = no,command = self.no)
170 self.but_yes.place(relx=0.4,rely=0.5,anchor='center')
171 self.but_no.place(relx=0.6,rely=0.5,anchor='center')
173 self.affiche_texte(self.texte)
174 centerwindow(self.fenetre)
184 class FenetreDeSelection(Fenetre):
185 """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.
186 Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.
188 def __init__(self,panel,item,appli,titre="",texte=""):
189 Fenetre.__init__(self,appli,titre=titre,texte=texte)
190 self.fenetre.configure(width = 320,height=400)
191 centerwindow(self.fenetre)
194 self.fenetre.title(titre)
195 self.but_save.configure(text="Ajouter",command=self.traite_selection)
196 # séparateur par défaut
197 self.separateur = ";"
198 # création de la zone de saisie du séparateur
199 l_separateurs_autorises = self.get_separateurs_autorises()
200 self.choix_sep = Pmw.ComboBox(self.frame_boutons,
201 label_text = "Séparateur :",
204 selectioncommand = self.choose_separateur,
205 scrolledlist_items = l_separateurs_autorises)
206 self.choix_sep.component('entry').configure(width=6)
207 self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')
208 self.choix_sep.selectitem(self.separateur)
210 self.but_quit.place_forget()
211 self.but_save.place_forget()
212 self.but_save.place(relx=0.6,rely=0.5,anchor='center')
213 self.but_quit.place(relx=0.8,rely=0.5,anchor='center')
215 def get_separateurs_autorises(self):
217 Retourne la liste des séparateurs autorisés
219 return ['espace',';',',']
221 def choose_separateur(self,nom_sep):
223 Affecte à self.separateur le caractère séparateur correspondant à nom_sep
225 if nom_sep == 'espace' :
226 self.separateur = ' '
228 self.separateur = nom_sep
230 def traite_selection(self):
231 """ Cette méthode effectue tous les traitements nécessaires pour vérifier
232 et affecter la liste de valeurs à l'objet réprésenté par self.item
234 # Récupère la liste des chaines de caractères de la zone sélectionnée
235 message,liste = self.recupere_liste()
236 if self.test_probleme(message,"Sélectionnez des données") == 0:
238 # Vérifie que le nombre de données est dans les limites attendues
239 message = self.verif_liste(liste)
240 if self.test_probleme(message,"Vérifiez le nombre de données") == 0:
242 # Crée une liste de valeurs du type attendu
243 message,liste_valeurs = self.creation_liste_valeurs(liste)
244 if self.test_probleme(message,"Vérifiez le type des données") == 0:
246 # Vérifie que chaque valeur est dans le domaine exigé
247 message = self.verif_valeurs(liste_valeurs)
248 if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:
250 # Ajoute les valeurs dans la liste de valeurs du mot-clé
251 self.ajouter_valeurs(liste_valeurs)
252 self.appli.affiche_infos("Liste de valeurs acceptée")
254 def test_probleme(self, message, message_eficas):
255 """ Cette méthode affiche un message d'erreur si message != ''
256 et retourne 0, sinon retourne 1 sans rien afficher.
259 showinfo("Problème",message)
260 self.fenetre.tkraise()
261 self.appli.affiche_infos(message_eficas)
266 def recupere_liste(self):
267 """ Cette méthode récupère le texte de la zone sélectionnée, construit et
268 retourne une liste avec les chaines qui se trouvent entre les séparateurs.
269 S'il n'y a pas de données selectionnées, elle retourne un message d'erreur
274 selection=self.fenetre.selection_get()
276 message = "Pas de donnée sélectionnée"
278 # les retours chariots doivent être interprétés comme des séparateurs
279 selection = string.replace(selection,'\n',self.separateur)
280 # on splitte la sélection suivant le caractère séparateur
281 liste_chaines = string.split(selection,self.separateur)
283 for chaine in liste_chaines:
284 chaine = string.strip(chaine)
285 if chaine != '' : l_chaines.append(chaine)
286 return message,l_chaines
288 def verif_liste(self, liste):
289 """ Cette méthode effectue des tests sur le nombre d'éléments de la liste
290 et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur
294 # nombre d'éléments sélectionnés
295 nombre_elements = len(liste)
296 # nombre d'éléments déja dans la liste du panel
297 nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())
298 multiplicite = self.item.GetMultiplicite()
299 if (nombre_elements % multiplicite) != 0:
300 message = "Vous devez sélectionner "+str(multiplicite)+" * n données"
302 nombre_valeurs = nombre_elements / multiplicite
303 cardinalite = self.item.GetMinMax()
304 if nombre_valeurs < cardinalite[0]:
305 message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"
307 if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):
308 message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"
313 def creation_liste_valeurs(self, liste):
314 """ Cette méthode crée et retourne une liste de valeurs du type attendu
315 par le mot-clé. La liste de valeurs est créée à partir de la liste
316 de chaines de caractères transmise.
318 type_attendu = self.item.GetType()[0]
319 if type_attendu == 'R':
320 return self.convertir(liste, f_conversion= float)
321 elif type_attendu == 'I':
322 return self.convertir(liste, f_conversion= int)
323 elif type_attendu == 'TXM':
324 return self.convertir(liste)
326 message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"
329 def convertir(self, liste, f_conversion=None):
330 """ Cette méthode essaie de convertir les éléments de la liste avec la
331 fonction f_conversion si elle existe, et retourne la liste des
332 éléments dans le type voulu en cas de succès, sinon retourne None.
339 liste_valeurs.append(f_conversion(chaine))
341 message = "Impossible de convertir "+chaine+" dans le type attendu"
344 liste_valeurs.append(chaine)
345 return message,liste_valeurs
347 def verif_valeurs(self, liste_valeurs):
348 """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque
349 élément est dans le domaine voulu.
352 for valeur in liste_valeurs:
353 test = self.item.IsInIntervalle(valeur)
355 intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])
356 message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"
360 def ajouter_valeurs(self, liste_valeurs):
361 """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""
362 liste = self.panel.Liste_valeurs.get_liste()
363 liste.extend(liste_valeurs)
364 self.panel.Liste_valeurs.put_liste(liste)
368 Cette classe permet de créer une boîte Dialog dans laquelle
369 on affiche un formulaire à remplir par l'utilisateur
371 def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):
372 if items in ((),[]) : return
376 self.fen_pere = fen_pere
377 self.obj_pere = obj_pere
379 self.command = commande
383 self.init_validateurs()
386 self.init_items_formulaire()
387 self.fenetre.activate(geometry='centerscreenalways')
389 def init_validateurs(self):
391 Crée le dictionnaire des validateurs des objets reconnus par le formulaire
393 self.d_validateurs = {}
394 self.d_validateurs['rep'] = self.repvalidator
395 self.d_validateurs['file'] = self.filevalidator
396 self.d_validateurs['cata']= self.catavalidator
398 def init_fenetre(self):
400 Crée la fenêtre Dialog
402 if self.mode == 'query':
403 buttons=('Valider','Annuler')
404 defaultbutton = 'Valider'
405 elif self.mode == 'display':
407 buttons=(self.command[0],'OK')
412 self.fenetre = Pmw.Dialog(self.fen_pere,
414 defaultbutton = defaultbutton,
416 command = self.execute)
417 self.fenetre.withdraw()
419 def init_texte(self):
421 Crée le label qui affiche le texte à l'intérieur du panneau
423 fonte=fontes.standard
424 fr_texte = Frame(self.fenetre.interior(),height=60)
425 fr_texte.pack(side='top',fill='x',expand=1)
426 Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
428 def init_items_formulaire(self):
430 Crée et affiche les items dans la boîte de dialogue
434 self.item_widgets = {}
436 for item in self.items:
437 if len(item[0])>length_maxi : length_maxi = len(item[0])
438 window = self.fenetre.interior()
439 for item in self.items :
440 label,nature,nom_var,defaut = item
441 # création de la frame
442 fr_item = Frame(window,height=40,width=700)
443 fr_item.pack(side='top',fill='x',expand=1)
445 Label(fr_item,text = label).place(relx=0.05,rely=0.4)
446 if nature in ('rep','file','cata'):
447 # création de l'entry
448 e_item = Entry(fr_item)
449 e_item.place(relx=0.5,rely=0.4,relwidth=0.45)
450 self.widgets.append(e_item)
451 self.item_widgets[item] = e_item
452 if defaut : e_item.insert(0,str(defaut))
453 elif nature == 'YesNo':
454 # création de la StringVar
456 setattr(self,'item_'+nom_var,var)
458 # création du radiobouton
459 rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')
460 rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')
461 rb1.place(relx=0.65,rely=0.5,anchor='center')
462 rb2.place(relx=0.80,rely=0.5,anchor='center')
463 self.widgets.append((rb1,rb2))
464 self.item_widgets[item] = var
465 # détermination de la méthode à appliquer sur les boutons
466 if self.mode == 'query':
467 function = self.active
468 elif self.mode == 'display':
469 function = self.inactive
472 # on applique la méthode sur les boutons (activation ou désactivation)
473 for widget in self.widgets :
474 if type(widget) == types.TupleType:
476 apply(function,(widg,),{})
478 apply(function,(widget,),{})
480 def active(self,widget):
482 Active le widget passé en argument
484 widget.configure(state='normal',bg='white')
486 def inactive(self,widget):
488 Inactive le widget passé en argument
490 if not isinstance(widget,Radiobutton) :
491 widget.configure(state='disabled',bg='gray95')
493 widget.configure(state='disabled')
495 # --------------------------------------------------------------------------------
496 # Validateurs des noms de répertoire, de fichiers et de catalogues
497 # -------------------------------------------------------------------------------
499 def repvalidator(self,text):
501 Teste si text peut faire référence à un répertoire ou non
502 Retourne 1 si valide, 0 sinon
504 return os.path.isdir(text),'Répertoire introuvable : %s' %text
506 def filevalidator(self,text):
508 Teste si text peut faire référence à un fichier ou non
509 Retourne 1 si valide, 0 sinon
511 return os.path.isfile(text),'Fichier introuvable : %s' %text
513 def catavalidator(self,text):
515 Teste si text est un chemin d'accès valide à un catalogue
516 Retourne 1 si valide, 0 sinon
518 return os.path.isfile(text),"Catalogue introuvable : %s" %text
520 # --------------------------------------------------------------------------------
521 # Méthodes callbacks des boutons et de fin
522 # --------------------------------------------------------------------------------
524 def execute(self,txt):
526 Cette commande est activée à chaque clic sur un bouton.
527 Redirige l'action sur la bonne méthode en fonction du bouton activé
531 elif txt in ('OK','Annuler'):
533 elif txt == 'Modifier':
534 self.resultat = apply(self.command[1],(),{})
535 self.fenetre.destroy()
537 print "Nom de bouton inconnu"
542 Commande qui termine le panneau et sauvegarde les nouvelles options
543 dans l'objet resultat (dictionnaire)
546 for item,widget in self.item_widgets.items():
549 valeur = widget.get()
550 if self.d_validateurs.has_key(type_var):
551 test = self.d_validateurs[type_var](valeur)
553 # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode
554 # sans tuer la fenêtre bien sûr
555 widget.selection_range(0,END)
557 dico[nom_var] = valeur
558 self.fenetre.destroy()
562 self.fenetre.destroy()
566 """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
567 en passant les commandes à lancer suivant différents bindings """
568 def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''):
573 self.selection = None
574 self.liste_commandes = liste_commandes
575 self.liste_marques = liste_marques
583 self.make_label_titre()
584 self.make_entry_filtre()
587 self.entry.component('entry').focus()
591 def make_label_titre(self):
592 """ Crée le label correspondant au titre """
593 if self.titre == '' : return
594 fonte_titre = fontes.standard_gras_souligne
595 self.label = Label(self.page,
598 self.label.pack(side='top',pady=2)
600 def make_entry_filtre(self):
601 """ Crée l'entry permettant à l'utilisateur d'entrer un filtre de sélection dans la liste """
602 if self.filtre != 'oui' : return
603 self.entry = Pmw.EntryField(self.page,labelpos='w',
604 label_text="Filtre :",
605 command=self.entry_changed)
606 self.entry.pack(side='top',pady=2)
608 def make_text_box(self):
609 """ Crée la fenêtre texte dans laquelle sera affichée la liste """
610 self.MCbox = Text (self.page,relief='sunken',bg='gray95',bd=2)
611 self.MCscroll = Scrollbar (self.page,command = self.MCbox.yview)
612 self.MCscroll.pack(side='right',fill ='y',pady=2)
613 self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
614 self.MCbox.configure(yscrollcommand=self.MCscroll.set)
616 def affiche_liste(self):
617 """ Affiche la liste dans la fenêtre"""
619 self.MCbox.config(state=NORMAL)
620 self.MCbox.delete(1.0,END)
621 for objet in self.liste :
622 if type(objet) == types.InstanceType:
627 elif type(objet) in (types.StringType,types.IntType):
629 elif type(objet) == types.FloatType :
630 #mot = repr_float(objet)
632 elif type(objet) == types.TupleType :
644 label = Label(self.MCbox,
646 fg = 'black',bg = 'gray95',justify = 'left')
647 self.dico_labels[mot]=label
648 liste_labels.append(label)
649 self.MCbox.window_create(END,
652 self.MCbox.insert(END,'\n')
653 if self.active == 'oui':
654 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))
655 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))
656 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))
658 for marque in self.liste_marques:
660 self.markitem(liste_labels[marque])
664 self.MCbox.config(state=DISABLED)
665 self.selection = None
667 def chooseitem(self,mot,label,commande):
668 """ Active la méthode de choix passée en argument"""
671 except AsException,e:
673 showerror(raison.split('\n')[0],raison)
675 def selectitem(self,mot,label,commande) :
676 """ Met l'item sélectionné (représenté par son label) en surbrillance
677 et lance la commande associée au double-clic"""
678 if self.selection != None :
679 self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
680 self.highlightitem(label)
681 self.selection = (mot,label,commande)
682 self.arg_selected = mot
685 def highlightitem(self,label) :
686 """ Met l'item représenté par son label en surbrillance """
687 label.configure(bg='#00008b',fg='white')
689 def markitem(self,label):
690 """ Met l'item (représenté par son label) en rouge """
691 label.configure(bg='gray95',fg='red')
693 def deselectitem(self,label,mot='',commande=None) :
694 """ Remet l'item (représenté par son label) en noir"""
695 label.configure(bg='gray95',fg='black')
696 self.arg_selected = ''
697 if commande != None : commande(mot)
699 def cherche_selected_item(self):
700 index=self.MCbox.index(self.selection[1])
701 lign,col=map(int,string.split(index,'.'))
704 def remove_selected_item(self):
705 index=self.MCbox.index(self.selection[1])
706 lign,col=map(int,string.split(index,'.'))
707 del self.liste[lign-1]
710 def entry_changed(self,event=None):
711 """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
712 de l'entry et frappe <Return>"""
713 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
714 filtre = self.entry.get()+"*"
715 FILTRE = string.upper(filtre)
716 for arg in self.liste :
717 if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
718 self.highlightitem(self.dico_labels[arg])
719 index = self.MCbox.index(self.dico_labels[arg])
720 self.MCbox.see(index)
721 self.arg_selected = arg
724 def get_liste_old(self):
727 # PN attention à la gestion des paramétres
728 # cela retourne H = 1 , et ni H, ni 1
730 # print val.__class__.__name__
733 for val in self.liste:
741 def put_liste(self,liste):
746 """ Cette classe permet d'afficher au lancement d'EFICAS le message
747 d'attente et la barre de progression"""
748 def __init__(self,master,message,barre ='oui'):
749 from Tools.foztools.foztools import Slider
750 fonte=fontes.standard12_gras
752 self.frame = Frame(self.master)
753 self.frame.pack(expand=1,fill='both')
754 self.mess = Label(self.frame,text=message,justify='center',
755 bd=2,relief='groove',font=fonte)
756 self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
757 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
758 fillColor='#00008b',width=200,height=30,
759 background='white',labelColor='red')
761 self.progress.frame.pack(in_=self.frame,side='top')
764 self.progress.frame.after(1000,self.update)
766 def configure(self,**options):
767 if options.has_key('message'):
768 self.mess.configure(text=options['message'])
769 if options.has_key('barre'):
770 if options['barre'] == 'oui' :
771 self.progress.frame.pack(in_=self.frame,side='top')
772 elif options['barre'] == 'non' :
773 self.progress.frame.pack_forget()
774 self.master.update_idletasks()
780 def update(self,event=None):
781 """ Permet de faire avancer la barre de progression """
784 bar.value = bar.value+self.increment
786 self.master.after(100,self.update)
790 def configure_barre(self,nb):
791 """ Calcule l'incrément de progression de la barre en fonction
792 du nombre d'opérations à effectuer afin que le compteur
793 soit à 100% à la fin des opérations"""
794 self.increment = 100./nb
795 self.progress.update()
797 class Ask_Format_Fichier :
799 Cette classe permet de créer une fenêtre Toplevel dans laquelle
800 on propose le choix du format de fichier de commandes à ouvrir
802 def __init__(self,appli):
803 self.fenetre = Toplevel()
804 self.fenetre.configure(width = 250,height=150)
805 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
806 self.fenetre.title("Choix du format du fichier de commandes")
807 # définition des frames
808 self.frame_texte = Frame(self.fenetre)
809 self.frame_radioboutons = Frame(self.fenetre)
810 self.frame_bouton_ok = Frame(self.fenetre)
811 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
812 self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
813 self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
814 # définition de la zone texte et du scrollbar
815 zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
816 zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
817 # définition des radioboutons
818 Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
819 variable=appli.format_fichier,value='Aster').pack(anchor='n')
820 Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
821 variable=appli.format_fichier,value='Python').pack(anchor='n')
822 # création du bouton OK
823 Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
824 # centrage de la fenêtre
825 centerwindow(self.fenetre)
828 self.fenetre.destroy()
830 class BARRE_K2000(Toplevel):
831 def __init__(self,master=None,text = ""):
832 Toplevel.__init__(self,master,relief='groove')
833 self.master.iconify()
834 self.geometry("250x100+0+0")
835 self.protocol("WM_DELETE_WINDOW",self.quit)
836 # frame principale dans self (= Toplevel)
837 self.frame = Frame(self)
838 self.frame.place(relwidth=1,relheight=1)
839 # frame contenant le texte à afficher
840 self.frame_text = Frame(self.frame)
841 self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
842 # frame contenant le canvas de la barre
843 self.frame_canv = Frame(self.frame)
844 self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
845 # canvas dans lequel sera affichée la barre K2000
846 self.canvas = Canvas(self.frame_canv)
847 self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
848 # on affiche le texte et la barre
849 self.build_text(text)
851 #self.overrideredirect(1)
852 # on active la barre ...
853 self.master.after(1000,self.launch)
854 # on centre la fenêtre
858 def build_text(self,text):
860 Affichage de text dans frame_text
862 self.texte_var = StringVar()
863 self.texte_var.set(text)
864 Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
866 def build_batons(self):
868 Construit la suite de bâtons dans le canvas
874 for i in range(0,40):
875 id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
876 self.l_batons.append(id)
880 Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
884 self.master.deiconify()
887 self.black = self.black+1
888 l_bat = self.l_batons[0:self.black+1]
890 elif self.sens == 'G':
891 self.black = self.black-1
892 l_bat = self.l_batons[self.black:]
896 if num_color < 10 : color = 'black'
897 elif num_color > 90 : color = 'white'
898 else: color = 'gray'+`num_color`
899 self.canvas.itemconfigure(bat,fill=color)
901 if self.black == len(self.l_batons) :
903 if self.black == 0 and self.sens == 'G':self.sens = 'D'
904 self.after(80,self.launch)
906 def update_text(self,new_text):
908 Remplace le texte affiché par new_text
910 self.texte_var.set(new_text)
915 class ListeChoixParGroupes(ListeChoix) :
917 Cette classe est utilisée pour afficher une liste de commandes classées par
918 groupes. L'utilisateur peut réaliser des actions de selection
919 qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
921 def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
922 active ='oui',filtre='non',titre=''):
925 self.liste_groupes = liste_groupes
926 self.dict_groupes = dict_groupes
928 self.selection = None
929 self.liste_commandes = liste_commandes
930 self.liste_marques = liste_marques
937 def affiche_liste(self):
938 """ Affiche la liste dans la fenêtre"""
940 self.MCbox.config(state=NORMAL)
941 self.MCbox.delete(1.0,END)
942 for grp in self.liste_groupes:
943 # On itère sur les groupes
944 if grp == "CACHE":continue
945 liste_commandes=self.dict_groupes[grp]
946 text="GROUPE<<<<<<<< "+grp+" "
947 text=text+">"*max(0,30-len(text))
948 label = Label(self.MCbox,
950 fg = 'black',bg = 'gray95',justify = 'left')
951 # On stocke la relation entre le nom de la commande et le label
952 self.dico_labels[grp]=label
953 liste_labels.append(label)
954 self.MCbox.window_create(END,
957 self.MCbox.insert(END,'\n')
958 for cmd in liste_commandes:
959 label = Label(self.MCbox,
961 fg = 'black',bg = 'gray95',justify = 'left')
962 # On stocke la relation entre le nom de la commande et le label
963 self.dico_labels[cmd]=label
964 self.MCbox.window_create(END,
967 self.MCbox.insert(END,'\n')
968 if self.active == 'oui':
969 label.bind(self.liste_commandes[0][0],
970 lambda e,s=self,c=self.liste_commandes[0][1],x=cmd,l=label : s.selectitem(x,l,c))
971 label.bind(self.liste_commandes[1][0],
972 lambda e,s=self,c=self.liste_commandes[1][1],x=cmd,l=label : s.deselectitem(l,x,c))
973 label.bind(self.liste_commandes[2][0],
974 lambda e,s=self,c=self.liste_commandes[2][1],x=cmd,l=label : s.chooseitem(x,l,c))
976 for marque in self.liste_marques:
978 self.markitem(liste_labels[marque])
982 self.MCbox.config(state=DISABLED)
983 self.selection = None
985 def entry_changed(self,event=None):
987 Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
988 de l'entry et frappe <Return>
990 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
991 filtre = self.entry.get()+"*"
992 FILTRE = string.upper(filtre)
994 # On cherche d'abord dans les noms de groupe
995 # puis dans les noms de commande groupe par groupe
997 for grp in self.liste_groupes:
998 if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
999 index = self.MCbox.index(self.dico_labels[grp])
1000 self.MCbox.see(index)
1001 # On ne selectionne pas le groupe
1002 #self.arg_selected = grp
1003 # On a trouve un groupe on arrete la recherche
1006 for grp in self.liste_groupes:
1007 for cmd in self.dict_groupes[grp] :
1008 if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
1009 self.highlightitem(self.dico_labels[cmd])
1010 index = self.MCbox.index(self.dico_labels[cmd])
1011 self.MCbox.see(index)
1012 self.arg_selected = cmd
1013 # On a trouve une commande on arrete la recherche