1 # CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
20 # ----------------------------------------------------------
21 # Cette classe sert à définir les widgets utilisés par
23 # ----------------------------------------------------------
27 import os,sys,re,string
29 from tkFileDialog import *
30 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
34 from utils import save_in_file
35 from centerwindow import centerwindow
37 from Noyau.N_utils import repr_float
40 """ Cette classe permet de créer une fenêtre Toplevel dans laquelle
41 on peut afficher un texte et qui permet de le sauver"""
42 def __init__(self,appli,titre="",texte=""):
44 self.fenetre = Toplevel()
45 self.fenetre.configure(width = 800,height=500)
46 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
47 self.fenetre.title("Visualisation du "+titre)
48 self.texte = string.replace(texte,'\r\n','\n')
50 fonte=fontes.standardcourier10
51 # définition des frames
52 self.frame_texte = Frame(self.fenetre)
53 self.frame_boutons = Frame(self.fenetre)
54 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.9)
55 self.frame_boutons.place(relheight=0.1,relx=0,rely=0.9,relwidth=1.)
56 # définition de la zone texte et du scrollbar
57 self.zone_texte = Text(self.frame_texte,font=fonte)
58 self.zone_texte.bind("<Key-Prior>", self.page_up)
59 self.zone_texte.bind("<Key-Next>", self.page_down)
60 self.zone_texte.bind("<Key-Up>", self.unit_up)
61 self.zone_texte.bind("<Key-Down>", self.unit_down)
62 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
63 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
64 self.scroll_v.pack(side='right',fill ='y')
65 #self.scroll_h.pack(side='bottom',fill ='x')
66 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
67 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
68 # définition des boutons
69 self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
70 self.but_save = Button(self.frame_boutons,text = "sauver",command = self.save)
71 self.but_quit.place(relx=0.4,rely=0.5,anchor='center')
72 self.but_save.place(relx=0.6,rely=0.5,anchor='center')
74 self.affiche_texte(self.texte)
75 centerwindow(self.fenetre)
77 def page_up(self,event):
78 event.widget.yview_scroll(-1, "page")
79 def page_down(self,event):
80 event.widget.yview_scroll(1, "page")
81 def unit_up(self,event):
82 event.widget.yview_scroll(-1, "unit")
83 def unit_down(self,event):
84 event.widget.yview_scroll(1, "unit")
87 self.fenetre.grab_set()
88 self.zone_texte.focus_set()
89 self.fenetre.wait_window(self.fenetre)
92 self.fenetre.destroy()
94 def efface_scroll(self):
95 """ Efface le scroll lorsqu'il n'est pas nécessaire : ne marche pas"""
96 self.scroll_v.pack_forget()
97 #self.scroll_h.pack_forget()
99 def affiche_texte(self,texte):
100 """ Affiche le texte dans la fenêtre """
102 self.zone_texte.insert(END,texte)
104 self.fenetre.update_idletasks()
105 x0,y0,x1,y1 = self.zone_texte.bbox(END)
106 if (y1-y0) < 300 : self.efface_scroll()
111 """ Permet de sauvegarder le texte dans un fichier dont on a demandé le nom
113 file = asksaveasfilename(defaultextension = '.comm',
114 #initialdir = self.appli.CONFIGURATION.rep_user,
115 initialdir = self.appli.CONFIGURATION.initialdir,
116 title="Sauvegarde du "+self.titre)
118 if not save_in_file(file,self.texte) :
119 showerror("Sauvegarde impossible",
120 "Impossible de sauvegarder le texte dans le fichier spécifié\n"+
121 "Vérifiez les droits d'écriture")
123 showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file)
125 class FenetreYesNo(Fenetre):
126 def __init__(self,appli,titre="",texte="",yes="Yes",no="No"):
128 self.fenetre = Toplevel()
129 self.fenetre.configure(width = 800,height=500)
130 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
131 self.fenetre.title(titre)
132 self.texte = string.replace(texte,'\r\n','\n')
134 fonte=fontes.standardcourier10
135 # définition des frames
136 self.frame_texte = Frame(self.fenetre)
137 self.frame_boutons = Frame(self.fenetre)
138 self.frame_boutons.place(relx=0,rely=0, relwidth=1.,relheight=0.1)
139 self.frame_texte.place( relx=0,rely=0.1, relwidth=1, relheight=0.9)
140 # définition de la zone texte et du scrollbar
141 self.zone_texte = Text(self.frame_texte,font=fonte)
142 self.zone_texte.bind("<Key-Prior>", self.page_up)
143 self.zone_texte.bind("<Key-Next>", self.page_down)
144 self.zone_texte.bind("<Key-Up>", self.unit_up)
145 self.zone_texte.bind("<Key-Down>", self.unit_down)
146 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
147 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
148 self.scroll_v.pack(side='right',fill ='y')
149 #self.scroll_h.pack(side='bottom',fill ='x')
150 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
151 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
152 # définition des boutons
153 self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes)
154 self.but_no = Button(self.frame_boutons,text = no,command = self.no)
155 self.but_yes.place(relx=0.4,rely=0.5,anchor='center')
156 self.but_no.place(relx=0.6,rely=0.5,anchor='center')
158 self.affiche_texte(self.texte)
159 centerwindow(self.fenetre)
169 class FenetreDeSelection(Fenetre):
170 """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.
\r
171 Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.
\r
173 def __init__(self,panel,item,appli,titre="",texte=""):
\r
174 Fenetre.__init__(self,appli,titre=titre,texte=texte)
\r
175 self.fenetre.configure(width = 320,height=400)
\r
176 centerwindow(self.fenetre)
179 self.fenetre.title(titre)
180 self.but_save.configure(text="Ajouter",command=self.traite_selection)
\r
181 # séparateur par défaut
\r
182 self.separateur = ";"
\r
183 # création de la zone de saisie du séparateur
\r
184 l_separateurs_autorises = self.get_separateurs_autorises()
\r
185 self.choix_sep = Pmw.ComboBox(self.frame_boutons,
\r
186 label_text = "Séparateur :",
\r
189 selectioncommand = self.choose_separateur,
\r
190 scrolledlist_items = l_separateurs_autorises)
\r
191 self.choix_sep.component('entry').configure(width=6)
\r
192 self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')
\r
193 self.choix_sep.selectitem(self.separateur)
\r
195 self.but_quit.place_forget()
\r
196 self.but_save.place_forget()
\r
197 self.but_save.place(relx=0.6,rely=0.5,anchor='center')
\r
198 self.but_quit.place(relx=0.8,rely=0.5,anchor='center')
\r
200 def get_separateurs_autorises(self):
\r
202 Retourne la liste des séparateurs autorisés
\r
204 return ['espace',';',',']
\r
206 def choose_separateur(self,nom_sep):
\r
208 Affecte à self.separateur le caractère séparateur correspondant à nom_sep
\r
210 if nom_sep == 'espace' :
\r
211 self.separateur = ' '
\r
213 self.separateur = nom_sep
\r
215 def traite_selection(self):
\r
216 """ Cette méthode effectue tous les traitements nécessaires pour vérifier
\r
217 et affecter la liste de valeurs à l'objet réprésenté par self.item
\r
219 # Récupère la liste des chaines de caractères de la zone sélectionnée
\r
220 message,liste = self.recupere_liste()
\r
221 if self.test_probleme(message,"Sélectionnez des données") == 0:
\r
223 # Vérifie que le nombre de données est dans les limites attendues
\r
224 message = self.verif_liste(liste)
\r
225 if self.test_probleme(message,"Vérifiez le nombre de données") == 0:
\r
227 # Crée une liste de valeurs du type attendu
\r
228 message,liste_valeurs = self.creation_liste_valeurs(liste)
\r
229 if self.test_probleme(message,"Vérifiez le type des données") == 0:
\r
231 # Vérifie que chaque valeur est dans le domaine exigé
\r
232 message = self.verif_valeurs(liste_valeurs)
\r
233 if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:
\r
235 # Ajoute les valeurs dans la liste de valeurs du mot-clé
\r
236 self.ajouter_valeurs(liste_valeurs)
\r
237 self.appli.affiche_infos("Liste de valeurs acceptée")
\r
239 def test_probleme(self, message, message_eficas):
\r
240 """ Cette méthode affiche un message d'erreur si message != ''
\r
241 et retourne 0, sinon retourne 1 sans rien afficher.
\r
244 showinfo("Problème",message)
\r
245 self.fenetre.tkraise()
\r
246 self.appli.affiche_infos(message_eficas)
\r
251 def recupere_liste(self):
\r
252 """ Cette méthode récupère le texte de la zone sélectionnée, construit et
\r
253 retourne une liste avec les chaines qui se trouvent entre les séparateurs.
\r
254 S'il n'y a pas de données selectionnées, elle retourne un message d'erreur
\r
259 selection=self.fenetre.selection_get()
\r
261 message = "Pas de donnée sélectionnée"
\r
262 return message,None
\r
263 # les retours chariots doivent être interprétés comme des séparateurs
\r
264 selection = string.replace(selection,'\n',self.separateur)
\r
265 # on splitte la sélection suivant le caractère séparateur
\r
266 liste_chaines = string.split(selection,self.separateur)
\r
268 for chaine in liste_chaines:
\r
269 chaine = string.strip(chaine)
\r
270 if chaine != '' : l_chaines.append(chaine)
\r
271 return message,l_chaines
\r
273 def verif_liste(self, liste):
\r
274 """ Cette méthode effectue des tests sur le nombre d'éléments de la liste
\r
275 et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur
\r
279 # nombre d'éléments sélectionnés
\r
280 nombre_elements = len(liste)
\r
281 # nombre d'éléments déja dans la liste du panel
\r
282 nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())
\r
283 multiplicite = self.item.GetMultiplicite()
\r
284 if (nombre_elements % multiplicite) != 0:
\r
285 message = "Vous devez sélectionner "+str(multiplicite)+" * n données"
\r
287 nombre_valeurs = nombre_elements / multiplicite
\r
288 cardinalite = self.item.GetMinMax()
\r
289 if nombre_valeurs < cardinalite[0]:
\r
290 message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"
\r
292 if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):
\r
293 message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"
\r
298 def creation_liste_valeurs(self, liste):
\r
299 """ Cette méthode crée et retourne une liste de valeurs du type attendu
\r
300 par le mot-clé. La liste de valeurs est créée à partir de la liste
\r
301 de chaines de caractères transmise.
\r
303 type_attendu = self.item.GetType()[0]
\r
304 if type_attendu == 'R':
\r
305 return self.convertir(liste, f_conversion= float)
\r
306 elif type_attendu == 'I':
\r
307 return self.convertir(liste, f_conversion= int)
\r
308 elif type_attendu == 'TXM':
\r
309 return self.convertir(liste)
\r
311 message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"
\r
312 return message,None
\r
314 def convertir(self, liste, f_conversion=None):
\r
315 """ Cette méthode essaie de convertir les éléments de la liste avec la
\r
316 fonction f_conversion si elle existe, et retourne la liste des
\r
317 éléments dans le type voulu en cas de succès, sinon retourne None.
\r
321 for chaine in liste:
\r
324 liste_valeurs.append(f_conversion(chaine))
\r
326 message = "Impossible de convertir "+chaine+" dans le type attendu"
\r
327 return message,None
\r
329 liste_valeurs.append(chaine)
\r
330 return message,liste_valeurs
\r
332 def verif_valeurs(self, liste_valeurs):
\r
333 """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque
\r
334 élément est dans le domaine voulu.
\r
337 for valeur in liste_valeurs:
\r
338 test = self.item.IsInIntervalle(valeur)
\r
340 intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])
\r
341 message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"
\r
345 def ajouter_valeurs(self, liste_valeurs):
\r
346 """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""
\r
347 liste = self.panel.Liste_valeurs.get_liste()
\r
348 liste.extend(liste_valeurs)
\r
349 self.panel.Liste_valeurs.put_liste(liste)
353 Cette classe permet de créer une boîte Dialog dans laquelle
354 on affiche un formulaire à remplir par l'utilisateur
\r
356 def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):
\r
357 if items in ((),[]) : return
361 self.fen_pere = fen_pere
362 self.obj_pere = obj_pere
364 self.command = commande
368 self.init_validateurs()
371 self.init_items_formulaire()
372 self.fenetre.activate(geometry='centerscreenalways')
374 def init_validateurs(self):
\r
376 Crée le dictionnaire des validateurs des objets reconnus par le formulaire
\r
378 self.d_validateurs = {}
\r
379 self.d_validateurs['rep'] = self.repvalidator
\r
380 self.d_validateurs['file'] = self.filevalidator
\r
381 self.d_validateurs['cata']= self.catavalidator
\r
383 def init_fenetre(self):
\r
385 Crée la fenêtre Dialog
\r
387 if self.mode == 'query':
388 buttons=('Valider','Annuler')
389 defaultbutton = 'Valider'
390 elif self.mode == 'display':
392 buttons=(self.command[0],'OK')
397 self.fenetre = Pmw.Dialog(self.fen_pere,
399 defaultbutton = defaultbutton,
401 command = self.execute)
\r
402 self.fenetre.withdraw()
404 def init_texte(self):
\r
406 Crée le label qui affiche le texte à l'intérieur du panneau
\r
408 fonte=fontes.standard
\r
409 fr_texte = Frame(self.fenetre.interior(),height=60)
\r
410 fr_texte.pack(side='top',fill='x',expand=1)
411 Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
413 def init_items_formulaire(self):
\r
415 Crée et affiche les items dans la boîte de dialogue
\r
419 self.item_widgets = {}
\r
421 for item in self.items:
422 if len(item[0])>length_maxi : length_maxi = len(item[0])
\r
423 window = self.fenetre.interior()
\r
424 for item in self.items :
\r
425 label,nature,nom_var,defaut = item
\r
426 # création de la frame
\r
427 fr_item = Frame(window,height=40,width=700)
\r
428 fr_item.pack(side='top',fill='x',expand=1)
\r
429 # création du label
\r
430 Label(fr_item,text = label).place(relx=0.05,rely=0.4)
\r
431 if nature in ('rep','file','cata'):
432 # création de l'entry
\r
433 e_item = Entry(fr_item)
\r
434 e_item.place(relx=0.5,rely=0.4,relwidth=0.45)
\r
435 self.widgets.append(e_item)
\r
436 self.item_widgets[item] = e_item
\r
437 if defaut : e_item.insert(0,str(defaut))
\r
438 elif nature == 'YesNo':
\r
439 # création de la StringVar
\r
441 setattr(self,'item_'+nom_var,var)
\r
443 # création du radiobouton
\r
444 rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')
\r
445 rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')
\r
446 rb1.place(relx=0.65,rely=0.5,anchor='center')
\r
447 rb2.place(relx=0.80,rely=0.5,anchor='center')
\r
448 self.widgets.append((rb1,rb2))
\r
449 self.item_widgets[item] = var
\r
450 # détermination de la méthode à appliquer sur les boutons
\r
451 if self.mode == 'query':
\r
452 function = self.active
\r
453 elif self.mode == 'display':
\r
454 function = self.inactive
\r
457 # on applique la méthode sur les boutons (activation ou désactivation)
\r
458 for widget in self.widgets :
\r
459 if type(widget) == types.TupleType:
\r
460 for widg in widget :
\r
461 apply(function,(widg,),{})
\r
463 apply(function,(widget,),{})
\r
465 def active(self,widget):
\r
467 Active le widget passé en argument
\r
469 widget.configure(state='normal',bg='white')
\r
471 def inactive(self,widget):
\r
473 Inactive le widget passé en argument
\r
475 if not isinstance(widget,Radiobutton) :
\r
476 widget.configure(state='disabled',bg='gray95')
\r
478 widget.configure(state='disabled')
\r
480 # --------------------------------------------------------------------------------
\r
481 # Validateurs des noms de répertoire, de fichiers et de catalogues
\r
482 # --------------------------------------------------------------------------------
\r
484 def repvalidator(self,text):
486 Teste si text peut faire référence à un répertoire ou non
\r
487 Retourne 1 si valide, 0 sinon
\r
489 return os.path.isdir(text),'Répertoire introuvable : %s' %text
491 def filevalidator(self,text):
493 Teste si text peut faire référence à un fichier ou non
\r
494 Retourne 1 si valide, 0 sinon
\r
496 return os.path.isfile(text),'Fichier introuvable : %s' %text
498 def catavalidator(self,text):
\r
500 Teste si text est un chemin d'accès valide à un catalogue
\r
501 Retourne 1 si valide, 0 sinon
\r
503 return os.path.isfile(text),"Catalogue introuvable : %s" %text
\r
505 # --------------------------------------------------------------------------------
\r
506 # Méthodes callbacks des boutons et de fin
\r
507 # --------------------------------------------------------------------------------
\r
509 def execute(self,txt):
\r
511 Cette commande est activée à chaque clic sur un bouton.
\r
512 Redirige l'action sur la bonne méthode en fonction du bouton activé
\r
516 elif txt in ('OK','Annuler'):
518 elif txt == 'Modifier':
519 self.resultat = apply(self.command[1],(),{})
520 self.fenetre.destroy()
522 print "Nom de bouton inconnu"
527 Commande qui termine le panneau et sauvegarde les nouvelles options
\r
528 dans l'objet resultat (dictionnaire)
\r
531 for item,widget in self.item_widgets.items():
\r
534 valeur = widget.get()
\r
535 if self.d_validateurs.has_key(type_var):
\r
536 test = self.d_validateurs[type_var](valeur)
\r
538 # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode
\r
539 # sans tuer la fenêtre bien sûr
\r
540 widget.selection_range(0,END)
\r
542 dico[nom_var] = valeur
543 self.fenetre.destroy()
547 self.fenetre.destroy()
551 """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
552 en passant les commandes à lancer suivant différents bindings """
553 def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''):
558 self.selection = None
559 self.liste_commandes = liste_commandes
560 self.liste_marques = liste_marques
568 self.make_label_titre()
569 self.make_entry_filtre()
572 self.entry.component('entry').focus()
576 def make_label_titre(self):
577 """ Crée le label correspondant au titre """
578 if self.titre == '' : return
579 fonte_titre = fontes.standard_gras_souligne
580 self.label = Label(self.page,
583 self.label.pack(side='top',pady=2)
585 def make_entry_filtre(self):
586 """ Crée l'entry permettant à l'utilisateur d'entrer un filtre de sélection dans la liste """
587 if self.filtre != 'oui' : return
588 self.entry = Pmw.EntryField(self.page,labelpos='w',
589 label_text="Filtre :",
590 command=self.entry_changed)
591 self.entry.pack(side='top',pady=2)
593 def make_text_box(self):
594 """ Crée la fenêtre texte dans laquelle sera affichée la liste """
595 self.MCbox = Text (self.page,relief='sunken',bg='gray95',bd=2)
596 self.MCscroll = Scrollbar (self.page,command = self.MCbox.yview)
597 self.MCscroll.pack(side='right',fill ='y',pady=2)
598 self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
599 self.MCbox.configure(yscrollcommand=self.MCscroll.set)
601 def affiche_liste(self):
602 """ Affiche la liste dans la fenêtre"""
604 self.MCbox.config(state=NORMAL)
605 self.MCbox.delete(1.0,END)
606 for objet in self.liste :
607 if type(objet) == types.InstanceType:
612 elif type(objet) in (types.StringType,types.IntType):
614 elif type(objet) == types.FloatType :
615 #mot = repr_float(objet)
619 label = Label(self.MCbox,
621 fg = 'black',bg = 'gray95',justify = 'left')
622 self.dico_labels[mot]=label
623 liste_labels.append(label)
624 self.MCbox.window_create(END,
627 self.MCbox.insert(END,'\n')
628 if self.active == 'oui':
629 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))
630 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))
631 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))
633 for marque in self.liste_marques:
635 self.markitem(liste_labels[marque])
639 self.MCbox.config(state=DISABLED)
640 self.selection = None
642 def chooseitem(self,mot,label,commande):
643 """ Active la méthode de choix passée en argument"""
646 def selectitem(self,mot,label,commande) :
647 """ Met l'item sélectionné (représenté par son label) en surbrillance
648 et lance la commande associée au double-clic"""
649 if self.selection != None :
650 self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
651 self.highlightitem(label)
652 self.selection = (mot,label,commande)
653 self.arg_selected = mot
656 def highlightitem(self,label) :
657 """ Met l'item représenté par son label en surbrillance """
658 label.configure(bg='#00008b',fg='white')
660 def markitem(self,label):
661 """ Met l'item (représenté par son label) en rouge """
662 label.configure(bg='gray95',fg='red')
664 def deselectitem(self,label,mot='',commande=None) :
665 """ Remet l'item (représenté par son label) en noir"""
666 label.configure(bg='gray95',fg='black')
667 self.arg_selected = ''
668 if commande != None : commande(mot)
670 def entry_changed(self,event=None):
671 """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
672 de l'entry et frappe <Return>"""
673 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
674 filtre = self.entry.get()+"*"
675 FILTRE = string.upper(filtre)
676 for arg in self.liste :
677 if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
678 self.highlightitem(self.dico_labels[arg])
679 index = self.MCbox.index(self.dico_labels[arg])
680 self.MCbox.see(index)
681 self.arg_selected = arg
684 def get_liste_old(self):
689 for val in self.liste:
697 def put_liste(self,liste):
702 """ Cette classe permet d'afficher au lancement d'EFICAS le message
703 d'attente et la barre de progression"""
704 def __init__(self,master,message,barre ='oui'):
705 from Tools.foztools.foztools import Slider
706 fonte=fontes.standard12_gras
708 self.frame = Frame(self.master)
709 self.frame.pack(expand=1,fill='both')
710 self.mess = Label(self.frame,text=message,justify='center',
711 bd=2,relief='groove',font=fonte)
712 self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
713 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
714 fillColor='#00008b',width=200,height=30,
715 background='white',labelColor='red')
717 self.progress.frame.pack(in_=self.frame,side='top')
720 self.progress.frame.after(1000,self.update)
722 def configure(self,**options):
723 if options.has_key('message'):
724 self.mess.configure(text=options['message'])
725 if options.has_key('barre'):
726 if options['barre'] == 'oui' :
727 self.progress.frame.pack(in_=self.frame,side='top')
728 elif options['barre'] == 'non' :
729 self.progress.frame.pack_forget()
730 self.master.update_idletasks()
736 def update(self,event=None):
737 """ Permet de faire avancer la barre de progression """
740 bar.value = bar.value+self.increment
742 self.master.after(100,self.update)
746 def configure_barre(self,nb):
747 """ Calcule l'incrément de progression de la barre en fonction
748 du nombre d'opérations à effectuer afin que le compteur
749 soit à 100% à la fin des opérations"""
750 self.increment = 100./nb
751 self.progress.update()
753 class Ask_Format_Fichier :
755 Cette classe permet de créer une fenêtre Toplevel dans laquelle
756 on propose le choix du format de fichier de commandes à ouvrir
\r
758 def __init__(self,appli):
759 self.fenetre = Toplevel()
760 self.fenetre.configure(width = 250,height=150)
761 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
762 self.fenetre.title("Choix du format du fichier de commandes")
763 # définition des frames
764 self.frame_texte = Frame(self.fenetre)
765 self.frame_radioboutons = Frame(self.fenetre)
766 self.frame_bouton_ok = Frame(self.fenetre)
767 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
768 self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
769 self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
770 # définition de la zone texte et du scrollbar
771 zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
772 zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
773 # définition des radioboutons
774 Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
775 variable=appli.format_fichier,value='Aster').pack(anchor='n')
776 Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
777 variable=appli.format_fichier,value='Python').pack(anchor='n')
778 # création du bouton OK
779 Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
780 # centrage de la fenêtre
781 centerwindow(self.fenetre)
784 self.fenetre.destroy()
786 class BARRE_K2000(Toplevel):
787 def __init__(self,master=None,text = ""):
788 Toplevel.__init__(self,master,relief='groove')
789 self.master.iconify()
790 self.geometry("250x100+0+0")
791 self.protocol("WM_DELETE_WINDOW",self.quit)
792 # frame principale dans self (= Toplevel)
793 self.frame = Frame(self)
794 self.frame.place(relwidth=1,relheight=1)
795 # frame contenant le texte à afficher
796 self.frame_text = Frame(self.frame)
797 self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
798 # frame contenant le canvas de la barre
799 self.frame_canv = Frame(self.frame)
800 self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
801 # canvas dans lequel sera affichée la barre K2000
802 self.canvas = Canvas(self.frame_canv)
803 self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
804 # on affiche le texte et la barre
805 self.build_text(text)
807 #self.overrideredirect(1)
808 # on active la barre ...
809 self.master.after(1000,self.launch)
810 # on centre la fenêtre
814 def build_text(self,text):
816 Affichage de text dans frame_text
818 self.texte_var = StringVar()
819 self.texte_var.set(text)
820 Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
822 def build_batons(self):
824 Construit la suite de bâtons dans le canvas
830 for i in range(0,40):
831 id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
832 self.l_batons.append(id)
836 Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
840 self.master.deiconify()
843 self.black = self.black+1
844 l_bat = self.l_batons[0:self.black+1]
846 elif self.sens == 'G':
847 self.black = self.black-1
848 l_bat = self.l_batons[self.black:]
852 if num_color < 10 : color = 'black'
853 elif num_color > 90 : color = 'white'
854 else: color = 'gray'+`num_color`
855 self.canvas.itemconfigure(bat,fill=color)
857 if self.black == len(self.l_batons) :
859 if self.black == 0 and self.sens == 'G':self.sens = 'D'
860 self.after(80,self.launch)
862 def update_text(self,new_text):
864 Remplace le texte affiché par new_text
866 self.texte_var.set(new_text)
871 class ListeChoixParGroupes(ListeChoix) :
873 Cette classe est utilisée pour afficher une liste de commandes classées par
874 groupes. L'utilisateur peut réaliser des actions de selection
875 qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
877 def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
878 active ='oui',filtre='non',titre=''):
881 self.liste_groupes = liste_groupes
882 self.dict_groupes = dict_groupes
884 self.selection = None
885 self.liste_commandes = liste_commandes
886 self.liste_marques = liste_marques
893 def affiche_liste(self):
894 """ Affiche la liste dans la fenêtre"""
896 self.MCbox.config(state=NORMAL)
897 self.MCbox.delete(1.0,END)
898 for grp in self.liste_groupes:
899 # On itère sur les groupes
900 if grp == "CACHE":continue
901 liste_commandes=self.dict_groupes[grp]
902 text="GROUPE<<<<<<<< "+grp+" "
903 text=text+">"*max(0,30-len(text))
904 label = Label(self.MCbox,
906 fg = 'black',bg = 'gray95',justify = 'left')
907 # On stocke la relation entre le nom de la commande et le label
908 self.dico_labels[grp]=label
909 liste_labels.append(label)
910 self.MCbox.window_create(END,
913 self.MCbox.insert(END,'\n')
914 for cmd in liste_commandes:
915 label = Label(self.MCbox,
917 fg = 'black',bg = 'gray95',justify = 'left')
918 # On stocke la relation entre le nom de la commande et le label
919 self.dico_labels[cmd]=label
920 self.MCbox.window_create(END,
923 self.MCbox.insert(END,'\n')
924 if self.active == 'oui':
925 label.bind(self.liste_commandes[0][0],
926 lambda e,s=self,c=self.liste_commandes[0][1],x=cmd,l=label : s.selectitem(x,l,c))
927 label.bind(self.liste_commandes[1][0],
928 lambda e,s=self,c=self.liste_commandes[1][1],x=cmd,l=label : s.deselectitem(l,x,c))
929 label.bind(self.liste_commandes[2][0],
930 lambda e,s=self,c=self.liste_commandes[2][1],x=cmd,l=label : s.chooseitem(x,l,c))
932 for marque in self.liste_marques:
934 self.markitem(liste_labels[marque])
938 self.MCbox.config(state=DISABLED)
939 self.selection = None
941 def entry_changed(self,event=None):
943 Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
944 de l'entry et frappe <Return>
946 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
947 filtre = self.entry.get()+"*"
948 FILTRE = string.upper(filtre)
950 # On cherche d'abord dans les noms de groupe
951 # puis dans les noms de commande groupe par groupe
953 for grp in self.liste_groupes:
954 if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
955 index = self.MCbox.index(self.dico_labels[grp])
956 self.MCbox.see(index)
957 # On ne selectionne pas le groupe
958 #self.arg_selected = grp
959 # On a trouve un groupe on arrete la recherche
962 for grp in self.liste_groupes:
963 for cmd in self.dict_groupes[grp] :
964 if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
965 self.highlightitem(self.dico_labels[cmd])
966 index = self.MCbox.index(self.dico_labels[cmd])
967 self.MCbox.see(index)
968 self.arg_selected = cmd
969 # On a trouve une commande on arrete la recherche