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
38 from Accas import AsException
41 """ Cette classe permet de créer une fenêtre Toplevel dans laquelle
42 on peut afficher un texte et qui permet de le sauver"""
43 def __init__(self,appli,titre="",texte=""):
45 self.fenetre = Toplevel()
46 self.fenetre.configure(width = 800,height=500)
47 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
48 self.fenetre.title("Visualisation du "+titre)
49 self.texte = string.replace(texte,'\r\n','\n')
51 fonte=fontes.standardcourier10
52 # définition des frames
53 self.frame_texte = Frame(self.fenetre)
54 self.frame_boutons = Frame(self.fenetre)
55 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.9)
56 self.frame_boutons.place(relheight=0.1,relx=0,rely=0.9,relwidth=1.)
57 # définition de la zone texte et du scrollbar
58 self.zone_texte = Text(self.frame_texte,font=fonte)
59 self.zone_texte.bind("<Key-Prior>", self.page_up)
60 self.zone_texte.bind("<Key-Next>", self.page_down)
61 self.zone_texte.bind("<Key-Up>", self.unit_up)
62 self.zone_texte.bind("<Key-Down>", self.unit_down)
63 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
64 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
65 self.scroll_v.pack(side='right',fill ='y')
66 #self.scroll_h.pack(side='bottom',fill ='x')
67 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
68 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
69 # définition des boutons
70 self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
71 self.but_save = Button(self.frame_boutons,text = "sauver",command = self.save)
72 self.but_quit.place(relx=0.4,rely=0.5,anchor='center')
73 self.but_save.place(relx=0.6,rely=0.5,anchor='center')
75 self.affiche_texte(self.texte)
76 centerwindow(self.fenetre)
78 def page_up(self,event):
79 event.widget.yview_scroll(-1, "page")
80 def page_down(self,event):
81 event.widget.yview_scroll(1, "page")
82 def unit_up(self,event):
83 event.widget.yview_scroll(-1, "unit")
84 def unit_down(self,event):
85 event.widget.yview_scroll(1, "unit")
88 self.fenetre.grab_set()
89 self.zone_texte.focus_set()
90 self.fenetre.wait_window(self.fenetre)
93 self.fenetre.destroy()
95 def efface_scroll(self):
96 """ Efface le scroll lorsqu'il n'est pas nécessaire : ne marche pas"""
97 self.scroll_v.pack_forget()
98 #self.scroll_h.pack_forget()
100 def affiche_texte(self,texte):
101 """ Affiche le texte dans la fenêtre """
103 self.zone_texte.insert(END,texte)
105 self.fenetre.update_idletasks()
106 x0,y0,x1,y1 = self.zone_texte.bbox(END)
107 if (y1-y0) < 300 : self.efface_scroll()
112 """ Permet de sauvegarder le texte dans un fichier dont on a demandé le nom
114 file = asksaveasfilename(defaultextension = '.comm',
115 #initialdir = self.appli.CONFIGURATION.rep_user,
116 initialdir = self.appli.CONFIGURATION.initialdir,
117 title="Sauvegarde du "+self.titre)
119 if not save_in_file(file,self.texte) :
120 showerror("Sauvegarde impossible",
121 "Impossible de sauvegarder le texte dans le fichier spécifié\n"+
122 "Vérifiez les droits d'écriture")
124 showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file)
126 class FenetreYesNo(Fenetre):
127 def __init__(self,appli,titre="",texte="",yes="Yes",no="No"):
129 self.fenetre = Toplevel()
130 self.fenetre.configure(width = 800,height=500)
131 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
132 self.fenetre.title(titre)
133 self.texte = string.replace(texte,'\r\n','\n')
135 fonte=fontes.standardcourier10
136 # définition des frames
137 self.frame_texte = Frame(self.fenetre)
138 self.frame_boutons = Frame(self.fenetre)
139 self.frame_boutons.place(relx=0,rely=0, relwidth=1.,relheight=0.1)
140 self.frame_texte.place( relx=0,rely=0.1, relwidth=1, relheight=0.9)
141 # définition de la zone texte et du scrollbar
142 self.zone_texte = Text(self.frame_texte,font=fonte)
143 self.zone_texte.bind("<Key-Prior>", self.page_up)
144 self.zone_texte.bind("<Key-Next>", self.page_down)
145 self.zone_texte.bind("<Key-Up>", self.unit_up)
146 self.zone_texte.bind("<Key-Down>", self.unit_down)
147 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
148 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
149 self.scroll_v.pack(side='right',fill ='y')
150 #self.scroll_h.pack(side='bottom',fill ='x')
151 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
152 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
153 # définition des boutons
154 self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes)
155 self.but_no = Button(self.frame_boutons,text = no,command = self.no)
156 self.but_yes.place(relx=0.4,rely=0.5,anchor='center')
157 self.but_no.place(relx=0.6,rely=0.5,anchor='center')
159 self.affiche_texte(self.texte)
160 centerwindow(self.fenetre)
170 class FenetreDeSelection(Fenetre):
171 """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.
172 Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.
174 def __init__(self,panel,item,appli,titre="",texte=""):
175 Fenetre.__init__(self,appli,titre=titre,texte=texte)
176 self.fenetre.configure(width = 320,height=400)
177 centerwindow(self.fenetre)
180 self.fenetre.title(titre)
181 self.but_save.configure(text="Ajouter",command=self.traite_selection)
182 # séparateur par défaut
183 self.separateur = ";"
184 # création de la zone de saisie du séparateur
185 l_separateurs_autorises = self.get_separateurs_autorises()
186 self.choix_sep = Pmw.ComboBox(self.frame_boutons,
187 label_text = "Séparateur :",
190 selectioncommand = self.choose_separateur,
191 scrolledlist_items = l_separateurs_autorises)
192 self.choix_sep.component('entry').configure(width=6)
193 self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')
194 self.choix_sep.selectitem(self.separateur)
196 self.but_quit.place_forget()
197 self.but_save.place_forget()
198 self.but_save.place(relx=0.6,rely=0.5,anchor='center')
199 self.but_quit.place(relx=0.8,rely=0.5,anchor='center')
201 def get_separateurs_autorises(self):
203 Retourne la liste des séparateurs autorisés
205 return ['espace',';',',']
207 def choose_separateur(self,nom_sep):
209 Affecte à self.separateur le caractère séparateur correspondant à nom_sep
211 if nom_sep == 'espace' :
212 self.separateur = ' '
214 self.separateur = nom_sep
216 def traite_selection(self):
217 """ Cette méthode effectue tous les traitements nécessaires pour vérifier
218 et affecter la liste de valeurs à l'objet réprésenté par self.item
220 # Récupère la liste des chaines de caractères de la zone sélectionnée
221 message,liste = self.recupere_liste()
222 if self.test_probleme(message,"Sélectionnez des données") == 0:
224 # Vérifie que le nombre de données est dans les limites attendues
225 message = self.verif_liste(liste)
226 if self.test_probleme(message,"Vérifiez le nombre de données") == 0:
228 # Crée une liste de valeurs du type attendu
229 message,liste_valeurs = self.creation_liste_valeurs(liste)
230 if self.test_probleme(message,"Vérifiez le type des données") == 0:
232 # Vérifie que chaque valeur est dans le domaine exigé
233 message = self.verif_valeurs(liste_valeurs)
234 if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:
236 # Ajoute les valeurs dans la liste de valeurs du mot-clé
237 self.ajouter_valeurs(liste_valeurs)
238 self.appli.affiche_infos("Liste de valeurs acceptée")
240 def test_probleme(self, message, message_eficas):
241 """ Cette méthode affiche un message d'erreur si message != ''
242 et retourne 0, sinon retourne 1 sans rien afficher.
245 showinfo("Problème",message)
246 self.fenetre.tkraise()
247 self.appli.affiche_infos(message_eficas)
252 def recupere_liste(self):
253 """ Cette méthode récupère le texte de la zone sélectionnée, construit et
254 retourne une liste avec les chaines qui se trouvent entre les séparateurs.
255 S'il n'y a pas de données selectionnées, elle retourne un message d'erreur
260 selection=self.fenetre.selection_get()
262 message = "Pas de donnée sélectionnée"
264 # les retours chariots doivent être interprétés comme des séparateurs
265 selection = string.replace(selection,'\n',self.separateur)
266 # on splitte la sélection suivant le caractère séparateur
267 liste_chaines = string.split(selection,self.separateur)
269 for chaine in liste_chaines:
270 chaine = string.strip(chaine)
271 if chaine != '' : l_chaines.append(chaine)
272 return message,l_chaines
274 def verif_liste(self, liste):
275 """ Cette méthode effectue des tests sur le nombre d'éléments de la liste
276 et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur
280 # nombre d'éléments sélectionnés
281 nombre_elements = len(liste)
282 # nombre d'éléments déja dans la liste du panel
283 nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())
284 multiplicite = self.item.GetMultiplicite()
285 if (nombre_elements % multiplicite) != 0:
286 message = "Vous devez sélectionner "+str(multiplicite)+" * n données"
288 nombre_valeurs = nombre_elements / multiplicite
289 cardinalite = self.item.GetMinMax()
290 if nombre_valeurs < cardinalite[0]:
291 message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"
293 if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):
294 message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"
299 def creation_liste_valeurs(self, liste):
300 """ Cette méthode crée et retourne une liste de valeurs du type attendu
301 par le mot-clé. La liste de valeurs est créée à partir de la liste
302 de chaines de caractères transmise.
304 type_attendu = self.item.GetType()[0]
305 if type_attendu == 'R':
306 return self.convertir(liste, f_conversion= float)
307 elif type_attendu == 'I':
308 return self.convertir(liste, f_conversion= int)
309 elif type_attendu == 'TXM':
310 return self.convertir(liste)
312 message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"
315 def convertir(self, liste, f_conversion=None):
316 """ Cette méthode essaie de convertir les éléments de la liste avec la
317 fonction f_conversion si elle existe, et retourne la liste des
318 éléments dans le type voulu en cas de succès, sinon retourne None.
325 liste_valeurs.append(f_conversion(chaine))
327 message = "Impossible de convertir "+chaine+" dans le type attendu"
330 liste_valeurs.append(chaine)
331 return message,liste_valeurs
333 def verif_valeurs(self, liste_valeurs):
334 """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque
335 élément est dans le domaine voulu.
338 for valeur in liste_valeurs:
339 test = self.item.IsInIntervalle(valeur)
341 intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])
342 message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"
346 def ajouter_valeurs(self, liste_valeurs):
347 """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""
348 liste = self.panel.Liste_valeurs.get_liste()
349 liste.extend(liste_valeurs)
350 self.panel.Liste_valeurs.put_liste(liste)
354 Cette classe permet de créer une boîte Dialog dans laquelle
355 on affiche un formulaire à remplir par l'utilisateur
357 def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):
358 if items in ((),[]) : return
362 self.fen_pere = fen_pere
363 self.obj_pere = obj_pere
365 self.command = commande
369 self.init_validateurs()
372 self.init_items_formulaire()
373 self.fenetre.activate(geometry='centerscreenalways')
375 def init_validateurs(self):
377 Crée le dictionnaire des validateurs des objets reconnus par le formulaire
379 self.d_validateurs = {}
380 self.d_validateurs['rep'] = self.repvalidator
381 self.d_validateurs['file'] = self.filevalidator
382 self.d_validateurs['cata']= self.catavalidator
384 def init_fenetre(self):
386 Crée la fenêtre Dialog
388 if self.mode == 'query':
389 buttons=('Valider','Annuler')
390 defaultbutton = 'Valider'
391 elif self.mode == 'display':
393 buttons=(self.command[0],'OK')
398 self.fenetre = Pmw.Dialog(self.fen_pere,
400 defaultbutton = defaultbutton,
402 command = self.execute)
403 self.fenetre.withdraw()
405 def init_texte(self):
407 Crée le label qui affiche le texte à l'intérieur du panneau
409 fonte=fontes.standard
410 fr_texte = Frame(self.fenetre.interior(),height=60)
411 fr_texte.pack(side='top',fill='x',expand=1)
412 Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
414 def init_items_formulaire(self):
416 Crée et affiche les items dans la boîte de dialogue
420 self.item_widgets = {}
422 for item in self.items:
423 if len(item[0])>length_maxi : length_maxi = len(item[0])
424 window = self.fenetre.interior()
425 for item in self.items :
426 label,nature,nom_var,defaut = item
427 # création de la frame
428 fr_item = Frame(window,height=40,width=700)
429 fr_item.pack(side='top',fill='x',expand=1)
431 Label(fr_item,text = label).place(relx=0.05,rely=0.4)
432 if nature in ('rep','file','cata'):
433 # création de l'entry
434 e_item = Entry(fr_item)
435 e_item.place(relx=0.5,rely=0.4,relwidth=0.45)
436 self.widgets.append(e_item)
437 self.item_widgets[item] = e_item
438 if defaut : e_item.insert(0,str(defaut))
439 elif nature == 'YesNo':
440 # création de la StringVar
442 setattr(self,'item_'+nom_var,var)
444 # création du radiobouton
445 rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')
446 rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')
447 rb1.place(relx=0.65,rely=0.5,anchor='center')
448 rb2.place(relx=0.80,rely=0.5,anchor='center')
449 self.widgets.append((rb1,rb2))
450 self.item_widgets[item] = var
451 # détermination de la méthode à appliquer sur les boutons
452 if self.mode == 'query':
453 function = self.active
454 elif self.mode == 'display':
455 function = self.inactive
458 # on applique la méthode sur les boutons (activation ou désactivation)
459 for widget in self.widgets :
460 if type(widget) == types.TupleType:
462 apply(function,(widg,),{})
464 apply(function,(widget,),{})
466 def active(self,widget):
468 Active le widget passé en argument
470 widget.configure(state='normal',bg='white')
472 def inactive(self,widget):
474 Inactive le widget passé en argument
476 if not isinstance(widget,Radiobutton) :
477 widget.configure(state='disabled',bg='gray95')
479 widget.configure(state='disabled')
481 # --------------------------------------------------------------------------------
482 # Validateurs des noms de répertoire, de fichiers et de catalogues
483 # -------------------------------------------------------------------------------
485 def repvalidator(self,text):
487 Teste si text peut faire référence à un répertoire ou non
488 Retourne 1 si valide, 0 sinon
490 return os.path.isdir(text),'Répertoire introuvable : %s' %text
492 def filevalidator(self,text):
494 Teste si text peut faire référence à un fichier ou non
495 Retourne 1 si valide, 0 sinon
497 return os.path.isfile(text),'Fichier introuvable : %s' %text
499 def catavalidator(self,text):
501 Teste si text est un chemin d'accès valide à un catalogue
502 Retourne 1 si valide, 0 sinon
504 return os.path.isfile(text),"Catalogue introuvable : %s" %text
506 # --------------------------------------------------------------------------------
507 # Méthodes callbacks des boutons et de fin
508 # --------------------------------------------------------------------------------
510 def execute(self,txt):
512 Cette commande est activée à chaque clic sur un bouton.
513 Redirige l'action sur la bonne méthode en fonction du bouton activé
517 elif txt in ('OK','Annuler'):
519 elif txt == 'Modifier':
520 self.resultat = apply(self.command[1],(),{})
521 self.fenetre.destroy()
523 print "Nom de bouton inconnu"
528 Commande qui termine le panneau et sauvegarde les nouvelles options
529 dans l'objet resultat (dictionnaire)
532 for item,widget in self.item_widgets.items():
535 valeur = widget.get()
536 if self.d_validateurs.has_key(type_var):
537 test = self.d_validateurs[type_var](valeur)
539 # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode
540 # sans tuer la fenêtre bien sûr
541 widget.selection_range(0,END)
543 dico[nom_var] = valeur
544 self.fenetre.destroy()
548 self.fenetre.destroy()
552 """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
553 en passant les commandes à lancer suivant différents bindings """
554 def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''):
559 self.selection = None
560 self.liste_commandes = liste_commandes
561 self.liste_marques = liste_marques
569 self.make_label_titre()
570 self.make_entry_filtre()
573 self.entry.component('entry').focus()
577 def make_label_titre(self):
578 """ Crée le label correspondant au titre """
579 if self.titre == '' : return
580 fonte_titre = fontes.standard_gras_souligne
581 self.label = Label(self.page,
584 self.label.pack(side='top',pady=2)
586 def make_entry_filtre(self):
587 """ Crée l'entry permettant à l'utilisateur d'entrer un filtre de sélection dans la liste """
588 if self.filtre != 'oui' : return
589 self.entry = Pmw.EntryField(self.page,labelpos='w',
590 label_text="Filtre :",
591 command=self.entry_changed)
592 self.entry.pack(side='top',pady=2)
594 def make_text_box(self):
595 """ Crée la fenêtre texte dans laquelle sera affichée la liste """
596 self.MCbox = Text (self.page,relief='sunken',bg='gray95',bd=2)
597 self.MCscroll = Scrollbar (self.page,command = self.MCbox.yview)
598 self.MCscroll.pack(side='right',fill ='y',pady=2)
599 self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
600 self.MCbox.configure(yscrollcommand=self.MCscroll.set)
602 def affiche_liste(self):
603 """ Affiche la liste dans la fenêtre"""
605 self.MCbox.config(state=NORMAL)
606 self.MCbox.delete(1.0,END)
607 for objet in self.liste :
608 if type(objet) == types.InstanceType:
613 elif type(objet) in (types.StringType,types.IntType):
615 elif type(objet) == types.FloatType :
616 #mot = repr_float(objet)
620 label = Label(self.MCbox,
622 fg = 'black',bg = 'gray95',justify = 'left')
623 self.dico_labels[mot]=label
624 liste_labels.append(label)
625 self.MCbox.window_create(END,
628 self.MCbox.insert(END,'\n')
629 if self.active == 'oui':
630 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))
631 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))
632 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))
634 for marque in self.liste_marques:
636 self.markitem(liste_labels[marque])
640 self.MCbox.config(state=DISABLED)
641 self.selection = None
643 def chooseitem(self,mot,label,commande):
644 """ Active la méthode de choix passée en argument"""
647 except AsException,e:
649 showerror(raison.split('\n')[0],raison)
651 def selectitem(self,mot,label,commande) :
652 """ Met l'item sélectionné (représenté par son label) en surbrillance
653 et lance la commande associée au double-clic"""
654 if self.selection != None :
655 self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
656 self.highlightitem(label)
657 self.selection = (mot,label,commande)
658 self.arg_selected = mot
661 def highlightitem(self,label) :
662 """ Met l'item représenté par son label en surbrillance """
663 label.configure(bg='#00008b',fg='white')
665 def markitem(self,label):
666 """ Met l'item (représenté par son label) en rouge """
667 label.configure(bg='gray95',fg='red')
669 def deselectitem(self,label,mot='',commande=None) :
670 """ Remet l'item (représenté par son label) en noir"""
671 label.configure(bg='gray95',fg='black')
672 self.arg_selected = ''
673 if commande != None : commande(mot)
675 def entry_changed(self,event=None):
676 """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
677 de l'entry et frappe <Return>"""
678 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
679 filtre = self.entry.get()+"*"
680 FILTRE = string.upper(filtre)
681 for arg in self.liste :
682 if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
683 self.highlightitem(self.dico_labels[arg])
684 index = self.MCbox.index(self.dico_labels[arg])
685 self.MCbox.see(index)
686 self.arg_selected = arg
689 def get_liste_old(self):
692 # PN attention à la gestion des paramétres
693 # cela retourne H = 1 , et ni H, ni 1
695 # print val.__class__.__name__
698 for val in self.liste:
706 def put_liste(self,liste):
711 """ Cette classe permet d'afficher au lancement d'EFICAS le message
712 d'attente et la barre de progression"""
713 def __init__(self,master,message,barre ='oui'):
714 from Tools.foztools.foztools import Slider
715 fonte=fontes.standard12_gras
717 self.frame = Frame(self.master)
718 self.frame.pack(expand=1,fill='both')
719 self.mess = Label(self.frame,text=message,justify='center',
720 bd=2,relief='groove',font=fonte)
721 self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
722 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
723 fillColor='#00008b',width=200,height=30,
724 background='white',labelColor='red')
726 self.progress.frame.pack(in_=self.frame,side='top')
729 self.progress.frame.after(1000,self.update)
731 def configure(self,**options):
732 if options.has_key('message'):
733 self.mess.configure(text=options['message'])
734 if options.has_key('barre'):
735 if options['barre'] == 'oui' :
736 self.progress.frame.pack(in_=self.frame,side='top')
737 elif options['barre'] == 'non' :
738 self.progress.frame.pack_forget()
739 self.master.update_idletasks()
745 def update(self,event=None):
746 """ Permet de faire avancer la barre de progression """
749 bar.value = bar.value+self.increment
751 self.master.after(100,self.update)
755 def configure_barre(self,nb):
756 """ Calcule l'incrément de progression de la barre en fonction
757 du nombre d'opérations à effectuer afin que le compteur
758 soit à 100% à la fin des opérations"""
759 self.increment = 100./nb
760 self.progress.update()
762 class Ask_Format_Fichier :
764 Cette classe permet de créer une fenêtre Toplevel dans laquelle
765 on propose le choix du format de fichier de commandes à ouvrir
767 def __init__(self,appli):
768 self.fenetre = Toplevel()
769 self.fenetre.configure(width = 250,height=150)
770 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
771 self.fenetre.title("Choix du format du fichier de commandes")
772 # définition des frames
773 self.frame_texte = Frame(self.fenetre)
774 self.frame_radioboutons = Frame(self.fenetre)
775 self.frame_bouton_ok = Frame(self.fenetre)
776 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
777 self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
778 self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
779 # définition de la zone texte et du scrollbar
780 zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
781 zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
782 # définition des radioboutons
783 Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
784 variable=appli.format_fichier,value='Aster').pack(anchor='n')
785 Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
786 variable=appli.format_fichier,value='Python').pack(anchor='n')
787 # création du bouton OK
788 Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
789 # centrage de la fenêtre
790 centerwindow(self.fenetre)
793 self.fenetre.destroy()
795 class BARRE_K2000(Toplevel):
796 def __init__(self,master=None,text = ""):
797 Toplevel.__init__(self,master,relief='groove')
798 self.master.iconify()
799 self.geometry("250x100+0+0")
800 self.protocol("WM_DELETE_WINDOW",self.quit)
801 # frame principale dans self (= Toplevel)
802 self.frame = Frame(self)
803 self.frame.place(relwidth=1,relheight=1)
804 # frame contenant le texte à afficher
805 self.frame_text = Frame(self.frame)
806 self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
807 # frame contenant le canvas de la barre
808 self.frame_canv = Frame(self.frame)
809 self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
810 # canvas dans lequel sera affichée la barre K2000
811 self.canvas = Canvas(self.frame_canv)
812 self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
813 # on affiche le texte et la barre
814 self.build_text(text)
816 #self.overrideredirect(1)
817 # on active la barre ...
818 self.master.after(1000,self.launch)
819 # on centre la fenêtre
823 def build_text(self,text):
825 Affichage de text dans frame_text
827 self.texte_var = StringVar()
828 self.texte_var.set(text)
829 Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
831 def build_batons(self):
833 Construit la suite de bâtons dans le canvas
839 for i in range(0,40):
840 id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
841 self.l_batons.append(id)
845 Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
849 self.master.deiconify()
852 self.black = self.black+1
853 l_bat = self.l_batons[0:self.black+1]
855 elif self.sens == 'G':
856 self.black = self.black-1
857 l_bat = self.l_batons[self.black:]
861 if num_color < 10 : color = 'black'
862 elif num_color > 90 : color = 'white'
863 else: color = 'gray'+`num_color`
864 self.canvas.itemconfigure(bat,fill=color)
866 if self.black == len(self.l_batons) :
868 if self.black == 0 and self.sens == 'G':self.sens = 'D'
869 self.after(80,self.launch)
871 def update_text(self,new_text):
873 Remplace le texte affiché par new_text
875 self.texte_var.set(new_text)
880 class ListeChoixParGroupes(ListeChoix) :
882 Cette classe est utilisée pour afficher une liste de commandes classées par
883 groupes. L'utilisateur peut réaliser des actions de selection
884 qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
886 def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
887 active ='oui',filtre='non',titre=''):
890 self.liste_groupes = liste_groupes
891 self.dict_groupes = dict_groupes
893 self.selection = None
894 self.liste_commandes = liste_commandes
895 self.liste_marques = liste_marques
902 def affiche_liste(self):
903 """ Affiche la liste dans la fenêtre"""
905 self.MCbox.config(state=NORMAL)
906 self.MCbox.delete(1.0,END)
907 for grp in self.liste_groupes:
908 # On itère sur les groupes
909 if grp == "CACHE":continue
910 liste_commandes=self.dict_groupes[grp]
911 text="GROUPE<<<<<<<< "+grp+" "
912 text=text+">"*max(0,30-len(text))
913 label = Label(self.MCbox,
915 fg = 'black',bg = 'gray95',justify = 'left')
916 # On stocke la relation entre le nom de la commande et le label
917 self.dico_labels[grp]=label
918 liste_labels.append(label)
919 self.MCbox.window_create(END,
922 self.MCbox.insert(END,'\n')
923 for cmd in liste_commandes:
924 label = Label(self.MCbox,
926 fg = 'black',bg = 'gray95',justify = 'left')
927 # On stocke la relation entre le nom de la commande et le label
928 self.dico_labels[cmd]=label
929 self.MCbox.window_create(END,
932 self.MCbox.insert(END,'\n')
933 if self.active == 'oui':
934 label.bind(self.liste_commandes[0][0],
935 lambda e,s=self,c=self.liste_commandes[0][1],x=cmd,l=label : s.selectitem(x,l,c))
936 label.bind(self.liste_commandes[1][0],
937 lambda e,s=self,c=self.liste_commandes[1][1],x=cmd,l=label : s.deselectitem(l,x,c))
938 label.bind(self.liste_commandes[2][0],
939 lambda e,s=self,c=self.liste_commandes[2][1],x=cmd,l=label : s.chooseitem(x,l,c))
941 for marque in self.liste_marques:
943 self.markitem(liste_labels[marque])
947 self.MCbox.config(state=DISABLED)
948 self.selection = None
950 def entry_changed(self,event=None):
952 Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
953 de l'entry et frappe <Return>
955 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
956 filtre = self.entry.get()+"*"
957 FILTRE = string.upper(filtre)
959 # On cherche d'abord dans les noms de groupe
960 # puis dans les noms de commande groupe par groupe
962 for grp in self.liste_groupes:
963 if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
964 index = self.MCbox.index(self.dico_labels[grp])
965 self.MCbox.see(index)
966 # On ne selectionne pas le groupe
967 #self.arg_selected = grp
968 # On a trouve un groupe on arrete la recherche
971 for grp in self.liste_groupes:
972 for cmd in self.dict_groupes[grp] :
973 if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
974 self.highlightitem(self.dico_labels[cmd])
975 index = self.MCbox.index(self.dico_labels[cmd])
976 self.MCbox.see(index)
977 self.arg_selected = cmd
978 # On a trouve une commande on arrete la recherche