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)
142 self.fenetre.destroy()
146 class FenetreYesNo(Fenetre):
147 def __init__(self,appli,titre="",texte="",yes="Yes",no="No"):
149 self.fenetre = Toplevel()
150 self.fenetre.configure(width = 800,height=500)
151 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
152 self.fenetre.title(titre)
153 self.texte = string.replace(texte,'\r\n','\n')
155 fonte=fontes.standardcourier10
156 # définition des frames
157 self.frame_texte = Frame(self.fenetre)
158 self.frame_boutons = Frame(self.fenetre)
159 self.frame_boutons.place(relx=0,rely=0, relwidth=1.,relheight=0.1)
160 self.frame_texte.place( relx=0,rely=0.1, relwidth=1, relheight=0.9)
161 # définition de la zone texte et du scrollbar
162 self.zone_texte = Text(self.frame_texte,font=fonte)
163 self.zone_texte.bind("<Key-Prior>", self.page_up)
164 self.zone_texte.bind("<Key-Next>", self.page_down)
165 self.zone_texte.bind("<Key-Up>", self.unit_up)
166 self.zone_texte.bind("<Key-Down>", self.unit_down)
167 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
168 #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
169 self.scroll_v.pack(side='right',fill ='y')
170 #self.scroll_h.pack(side='bottom',fill ='x')
171 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
172 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
173 # définition des boutons
174 self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes)
175 self.but_no = Button(self.frame_boutons,text = no,command = self.no)
176 self.but_yes.place(relx=0.4,rely=0.5,anchor='center')
177 self.but_no.place(relx=0.6,rely=0.5,anchor='center')
179 self.affiche_texte(self.texte)
180 centerwindow(self.fenetre)
190 class FenetreDeSelection(Fenetre):
191 """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.
192 Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.
194 def __init__(self,panel,item,appli,titre="",texte="",cardinal=1):
195 Fenetre.__init__(self,appli,titre=titre,texte=texte)
196 self.frame_boutons.place_forget()
197 self.frame_texte.place_forget()
198 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.8)
199 self.frame_boutons.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
201 self.cardinal=cardinal
202 self.fenetre.configure(width = 320,height=400)
203 centerwindow(self.fenetre)
206 self.fenetre.title(titre)
207 self.but_save.configure(text="Ajouter",command=self.traite_selection)
208 # séparateur par défaut
209 self.separateur = ";"
210 # création de la zone de saisie du séparateur
211 l_separateurs_autorises = self.get_separateurs_autorises()
212 self.choix_sep = Pmw.ComboBox(self.frame_boutons,
213 label_text = "Séparateur :",
216 selectioncommand = self.choose_separateur,
217 scrolledlist_items = l_separateurs_autorises)
218 self.choix_sep.component('entry').configure(width=6)
219 self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')
220 self.choix_sep.selectitem(self.separateur)
222 self.but_quit.place_forget()
223 self.but_save.place_forget()
224 self.but_all = Button(self.frame_boutons,text = "Tout Sélectionner", command=self.tout)
225 self.but_save.place(relx=0.6,rely=0.6,anchor='center')
226 self.but_quit.place(relx=0.8,rely=0.6,anchor='center')
227 self.but_all.place(relx=0.7,rely=0.2,anchor='center')
230 def get_separateurs_autorises(self):
232 Retourne la liste des séparateurs autorisés
234 return ['espace',';',',']
236 def choose_separateur(self,nom_sep):
238 Affecte à self.separateur le caractère séparateur correspondant à nom_sep
240 if nom_sep == 'espace' :
241 self.separateur = ' '
243 self.separateur = nom_sep
247 texte=self.texte.splitlines()
249 for mot in string.split(l,self.separateur):
251 self.traite_selection(liste)
253 def traite_selection(self,liste=None):
254 """ Cette méthode effectue tous les traitements nécessaires pour vérifier
255 et affecter la liste de valeurs à l'objet réprésenté par self.item
257 # Récupère la liste des chaines de caractères de la zone sélectionnée
260 message,liste = self.recupere_liste()
261 if self.test_probleme(message,"Sélectionnez des données") == 0:
263 # Vérifie que le nombre de données est dans les limites attendues
264 message = self.verif_liste(liste)
265 if self.test_probleme(message,"Vérifiez le nombre de données") == 0:
267 # Crée une liste de valeurs du type attendu
268 message,liste_valeurs = self.creation_liste_valeurs(liste)
269 if self.test_probleme(message,"Vérifiez le type des données") == 0:
271 # Vérifie que chaque valeur est dans le domaine exigé
272 message = self.verif_valeurs(liste_valeurs)
273 if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:
275 # Ajoute les valeurs dans la liste de valeurs du mot-clé
276 if self.cardinal != 1 :
280 if (len(liste_valeurs)%nb != 0):
281 message="La cardinalité n'est pas correcte"
282 self.test_probleme(message,"On attend des tuples")
284 for i in range(len(liste_valeurs)/nb) :
286 t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1])
288 t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1], liste_valeurs[i*nb+2])
290 print "probleme : prevenir la maintenance Eficas"
293 liste_valeurs=l_valeurs
294 self.ajouter_valeurs(liste_valeurs)
295 self.appli.affiche_infos("Liste de valeurs acceptée")
297 def test_probleme(self, message, message_eficas):
298 """ Cette méthode affiche un message d'erreur si message != ''
299 et retourne 0, sinon retourne 1 sans rien afficher.
302 showinfo("Problème",message)
303 self.fenetre.tkraise()
304 self.appli.affiche_infos(message_eficas)
309 def recupere_liste(self):
310 """ Cette méthode récupère le texte de la zone sélectionnée, construit et
311 retourne une liste avec les chaines qui se trouvent entre les séparateurs.
312 S'il n'y a pas de données selectionnées, elle retourne un message d'erreur
317 selection=self.fenetre.selection_get()
319 message = "Pas de donnée sélectionnée"
321 # les retours chariots doivent être interprétés comme des séparateurs
322 selection = string.replace(selection,'\n',self.separateur)
323 # on splitte la sélection suivant le caractère séparateur
324 liste_chaines = string.split(selection,self.separateur)
326 for chaine in liste_chaines:
327 chaine = string.strip(chaine)
328 if chaine != '' : l_chaines.append(chaine)
329 return message,l_chaines
331 def verif_liste(self, liste):
332 """ Cette méthode effectue des tests sur le nombre d'éléments de la liste
333 et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur
337 # nombre d'éléments sélectionnés
338 nombre_elements = len(liste)
339 # nombre d'éléments déja dans la liste du panel
340 nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())
341 multiplicite = self.item.GetMultiplicite()
342 if (nombre_elements % multiplicite) != 0:
343 message = "Vous devez sélectionner "+str(multiplicite)+" * n données"
345 nombre_valeurs = nombre_elements / multiplicite
346 cardinalite = self.item.GetMinMax()
347 if nombre_valeurs < cardinalite[0]:
348 message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"
350 if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):
351 message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"
356 def creation_liste_valeurs(self, liste):
357 """ Cette méthode crée et retourne une liste de valeurs du type attendu
358 par le mot-clé. La liste de valeurs est créée à partir de la liste
359 de chaines de caractères transmise.
361 type_attendu = self.item.GetType()[0]
362 if type_attendu == 'R':
363 return self.convertir(liste, f_conversion= float)
364 elif type_attendu == 'I':
365 return self.convertir(liste, f_conversion= int)
366 elif type_attendu == 'TXM':
367 return self.convertir(liste)
369 message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"
372 def convertir(self, liste, f_conversion=None):
373 """ Cette méthode essaie de convertir les éléments de la liste avec la
374 fonction f_conversion si elle existe, et retourne la liste des
375 éléments dans le type voulu en cas de succès, sinon retourne None.
382 liste_valeurs.append(f_conversion(chaine))
384 message = "Impossible de convertir "+chaine+" dans le type attendu"
387 liste_valeurs.append(chaine)
388 return message,liste_valeurs
390 def verif_valeurs(self, liste_valeurs):
391 """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque
392 élément est dans le domaine voulu.
395 for valeur in liste_valeurs:
396 test = self.item.IsInIntervalle(valeur)
398 intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])
399 message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"
403 def ajouter_valeurs(self, liste_valeurs):
404 """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""
405 liste = self.panel.Liste_valeurs.get_liste()
406 liste.extend(liste_valeurs)
407 self.panel.Liste_valeurs.put_liste(liste)
409 class FenetreDeParametre(Fenetre) :
410 def __init__(self,parent,item,appli,texte):
413 self.fenetre = Toplevel()
414 self.fenetre.configure(width = 250,height=100)
415 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
416 self.fenetre.title("Parametres")
417 self.titre = "Parametres"
418 self.texte = string.replace(texte,'\r\n','\n')
419 fonte=fontes.standardcourier10
421 # définition des frames
422 self.frame_texte = Frame(self.fenetre)
423 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.7)
424 # définition de la zone texte et du scrollbar
425 self.zone_texte = Text(self.frame_texte,font=fonte)
426 self.zone_texte.bind("<Key-Prior>", self.page_up)
427 self.zone_texte.bind("<Key-Next>", self.page_down)
428 self.zone_texte.bind("<Key-Up>", self.unit_up)
429 self.zone_texte.bind("<Key-Down>", self.unit_down)
430 self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
431 self.scroll_v.pack(side='right',fill ='y')
432 self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
433 self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
435 self.affiche_texte(self.texte)
436 self.zone_texte.config(state="disabled")
438 # définition des boutons
439 self.frame_boutons = Frame(self.fenetre)
440 self.frame_boutons.place(relheight=0.3,relx=0,rely=0.65,relwidth=1.)
441 self.label1 = Label(self.frame_boutons,text="surligner la")
442 self.label2 = Label(self.frame_boutons,text="ligne entière")
443 self.label1.place(relx=0.1,rely=0)
444 self.label2.place(relx=0.1,rely=0.5)
445 self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
446 self.but_save = Button(self.frame_boutons,text = "Choisir",command = self.Choisir)
447 self.but_save.place(relx=0.6,rely=0,relheight=1)
448 self.but_quit.place(relx=0.8,rely=0,relheight=1)
453 selection=self.zone_texte.selection_get()
455 showerror("Pas de donnée sélectionnée",
456 "Selectionner un parametre")
458 for param in selection.splitlines():
459 nomparam=param[0:param.find("=")-1]
461 l_param=l_param+nomparam+','
462 self.parent.entry.delete(0,Tkinter.END)
463 self.parent.entry.insert(0,l_param[0:-1])
464 self.parent.valid_valeur()
469 Cette classe permet de créer une boîte Dialog dans laquelle
470 on affiche un formulaire à remplir par l'utilisateur
472 def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):
473 if items in ((),[]) : return
477 self.fen_pere = fen_pere
478 self.obj_pere = obj_pere
480 self.command = commande
484 self.init_validateurs()
487 self.init_items_formulaire()
488 self.fenetre.activate(geometry='centerscreenalways')
490 def init_validateurs(self):
492 Crée le dictionnaire des validateurs des objets reconnus par le formulaire
494 self.d_validateurs = {}
495 self.d_validateurs['rep'] = self.repvalidator
496 self.d_validateurs['file'] = self.filevalidator
497 self.d_validateurs['cata']= self.catavalidator
499 def init_fenetre(self):
501 Crée la fenêtre Dialog
503 if self.mode == 'query':
504 buttons=('Valider','Annuler')
505 defaultbutton = 'Valider'
506 elif self.mode == 'display':
508 buttons=(self.command[0],'OK')
513 self.fenetre = Pmw.Dialog(self.fen_pere,
515 defaultbutton = defaultbutton,
517 command = self.execute)
518 self.fenetre.withdraw()
520 def init_texte(self):
522 Crée le label qui affiche le texte à l'intérieur du panneau
524 fonte=fontes.standard
525 fr_texte = Frame(self.fenetre.interior(),height=60)
526 fr_texte.pack(side='top',fill='x',expand=1)
527 Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
529 def init_items_formulaire(self):
531 Crée et affiche les items dans la boîte de dialogue
535 self.item_widgets = {}
537 for item in self.items:
538 if len(item[0])>length_maxi : length_maxi = len(item[0])
539 window = self.fenetre.interior()
540 for item in self.items :
541 label,nature,nom_var,defaut = item
542 # création de la frame
543 fr_item = Frame(window,height=40,width=700)
544 fr_item.pack(side='top',fill='x',expand=1)
546 Label(fr_item,text = label).place(relx=0.05,rely=0.4)
547 if nature in ('rep','file','cata'):
548 # création de l'entry
549 e_item = Entry(fr_item)
550 e_item.place(relx=0.5,rely=0.4,relwidth=0.45)
551 self.widgets.append(e_item)
552 self.item_widgets[item] = e_item
553 if defaut : e_item.insert(0,str(defaut))
554 elif nature == 'YesNo':
555 # création de la StringVar
557 setattr(self,'item_'+nom_var,var)
559 # création du radiobouton
560 rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')
561 rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')
562 rb1.place(relx=0.65,rely=0.5,anchor='center')
563 rb2.place(relx=0.80,rely=0.5,anchor='center')
564 self.widgets.append((rb1,rb2))
565 self.item_widgets[item] = var
566 # détermination de la méthode à appliquer sur les boutons
567 if self.mode == 'query':
568 function = self.active
569 elif self.mode == 'display':
570 function = self.inactive
573 # on applique la méthode sur les boutons (activation ou désactivation)
574 for widget in self.widgets :
575 if type(widget) == types.TupleType:
577 apply(function,(widg,),{})
579 apply(function,(widget,),{})
581 def active(self,widget):
583 Active le widget passé en argument
585 widget.configure(state='normal',bg='white')
587 def inactive(self,widget):
589 Inactive le widget passé en argument
591 if not isinstance(widget,Radiobutton) :
592 widget.configure(state='disabled',bg='gray95')
594 widget.configure(state='disabled')
596 # --------------------------------------------------------------------------------
597 # Validateurs des noms de répertoire, de fichiers et de catalogues
598 # -------------------------------------------------------------------------------
600 def repvalidator(self,text):
602 Teste si text peut faire référence à un répertoire ou non
603 Retourne 1 si valide, 0 sinon
605 return os.path.isdir(text),'Répertoire introuvable : %s' %text
607 def filevalidator(self,text):
609 Teste si text peut faire référence à un fichier ou non
610 Retourne 1 si valide, 0 sinon
612 return os.path.isfile(text),'Fichier introuvable : %s' %text
614 def catavalidator(self,text):
616 Teste si text est un chemin d'accès valide à un catalogue
617 Retourne 1 si valide, 0 sinon
619 return os.path.isfile(text),"Catalogue introuvable : %s" %text
621 # --------------------------------------------------------------------------------
622 # Méthodes callbacks des boutons et de fin
623 # --------------------------------------------------------------------------------
625 def execute(self,txt):
627 Cette commande est activée à chaque clic sur un bouton.
628 Redirige l'action sur la bonne méthode en fonction du bouton activé
632 elif txt in ('OK','Annuler'):
634 elif txt == 'Modifier':
635 self.resultat = apply(self.command[1],(),{})
636 self.fenetre.destroy()
638 print "Nom de bouton inconnu"
643 Commande qui termine le panneau et sauvegarde les nouvelles options
644 dans l'objet resultat (dictionnaire)
647 for item,widget in self.item_widgets.items():
650 valeur = widget.get()
651 if self.d_validateurs.has_key(type_var):
652 test = self.d_validateurs[type_var](valeur)
654 # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode
655 # sans tuer la fenêtre bien sûr
656 widget.selection_range(0,END)
658 dico[nom_var] = valeur
659 self.fenetre.destroy()
663 self.fenetre.destroy()
667 """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
668 en passant les commandes à lancer suivant différents bindings """
669 def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''):
674 self.selection = None
675 self.liste_commandes = liste_commandes
676 self.liste_marques = liste_marques
684 self.make_label_titre()
685 self.make_entry_filtre()
688 self.entry.component('entry').focus()
692 def make_label_titre(self):
693 """ Crée le label correspondant au titre """
694 if self.titre == '' : return
695 fonte_titre = fontes.standard_gras_souligne
696 self.label = Label(self.page,
699 self.label.pack(side='top',pady=2)
701 def make_entry_filtre(self):
702 """ Crée l'entry permettant à l'utilisateur d'entrer un filtre de sélection dans la liste """
703 if self.filtre != 'oui' : return
704 self.entry = Pmw.EntryField(self.page,labelpos='w',
705 label_text="Filtre :",
706 command=self.entry_changed)
707 self.entry.pack(side='top',pady=2)
709 def make_text_box(self):
710 """ Crée la fenêtre texte dans laquelle sera affichée la liste """
711 self.MCbox = Text (self.page,relief='sunken',bg='gray95',bd=2)
712 self.MCscroll = Scrollbar (self.page,command = self.MCbox.yview)
713 self.MCscroll.pack(side='right',fill ='y',pady=2)
714 self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
715 self.MCbox.configure(yscrollcommand=self.MCscroll.set)
717 def affiche_liste(self):
718 """ Affiche la liste dans la fenêtre"""
720 self.MCbox.config(state=NORMAL)
721 self.MCbox.delete(1.0,END)
722 for objet in self.liste :
723 if type(objet) == types.InstanceType:
728 elif type(objet) in (types.StringType,types.IntType):
730 elif type(objet) == types.FloatType :
731 #mot = repr_float(objet)
733 elif type(objet) == types.TupleType :
745 label = Label(self.MCbox,
747 fg = 'black',bg = 'gray95',justify = 'left')
748 self.dico_labels[mot]=label
749 liste_labels.append(label)
750 self.MCbox.window_create(END,
753 self.MCbox.insert(END,'\n')
754 if self.active == 'oui':
755 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))
756 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))
757 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))
759 for marque in self.liste_marques:
761 self.markitem(liste_labels[marque])
765 self.MCbox.config(state=DISABLED)
766 self.selection = None
768 def clear_marque(self):
770 self.dico_labels[self.arg_selected].configure(bg='gray95',fg='black')
771 self.arg_selected = ''
775 def surligne(self,marque):
777 self.highlightitem(self.dico_labels[marque])
778 self.arg_selected = marque
782 def chooseitem(self,mot,label,commande):
783 """ Active la méthode de choix passée en argument"""
786 except AsException,e:
788 showerror(raison.split('\n')[0],raison)
790 def selectitem(self,mot,label,commande) :
791 """ Met l'item sélectionné (représenté par son label) en surbrillance
792 et lance la commande associée au double-clic"""
794 if self.selection != None :
795 self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
796 self.highlightitem(label)
797 self.selection = (mot,label,commande)
798 self.arg_selected = mot
801 def highlightitem(self,label) :
802 """ Met l'item représenté par son label en surbrillance """
803 label.configure(bg='#00008b',fg='white')
805 def markitem(self,label):
806 """ Met l'item (représenté par son label) en rouge """
807 label.configure(bg='gray95',fg='red')
809 def deselectitem(self,label,mot='',commande=None) :
810 """ Remet l'item (représenté par son label) en noir"""
811 label.configure(bg='gray95',fg='black')
812 self.arg_selected = ''
813 if commande != None : commande(mot)
815 def cherche_selected_item(self):
816 index=self.MCbox.index(self.selection[1])
817 lign,col=map(int,string.split(index,'.'))
820 def remove_selected_item(self):
821 index=self.MCbox.index(self.selection[1])
822 lign,col=map(int,string.split(index,'.'))
823 del self.liste[lign-1]
826 def entry_changed(self,event=None):
827 """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
828 de l'entry et frappe <Return>"""
829 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
830 filtre = self.entry.get()+"*"
831 FILTRE = string.upper(filtre)
832 for arg in self.liste :
833 if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
834 self.highlightitem(self.dico_labels[arg])
835 index = self.MCbox.index(self.dico_labels[arg])
836 self.MCbox.see(index)
837 self.arg_selected = arg
840 def get_liste_old(self):
843 # PN attention à la gestion des paramétres
844 # cela retourne H = 1 , et ni H, ni 1
846 # print val.__class__.__name__
849 for val in self.liste:
857 def put_liste(self,liste):
862 """ Cette classe permet d'afficher au lancement d'EFICAS le message
863 d'attente et la barre de progression"""
864 def __init__(self,master,message,barre ='oui'):
865 from Tools.foztools.foztools import Slider
866 fonte=fontes.standard12_gras
868 self.frame = Frame(self.master)
869 self.frame.pack(expand=1,fill='both')
870 self.mess = Label(self.frame,text=message,justify='center',
871 bd=2,relief='groove',font=fonte)
872 self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
873 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
874 fillColor='#00008b',width=200,height=30,
875 background='white',labelColor='red')
877 self.progress.frame.pack(in_=self.frame,side='top')
880 self.progress.frame.after(1000,self.update)
882 def configure(self,**options):
883 if options.has_key('message'):
884 self.mess.configure(text=options['message'])
885 if options.has_key('barre'):
886 if options['barre'] == 'oui' :
887 self.progress.frame.pack(in_=self.frame,side='top')
888 elif options['barre'] == 'non' :
889 self.progress.frame.pack_forget()
890 self.master.update_idletasks()
896 def update(self,event=None):
897 """ Permet de faire avancer la barre de progression """
900 bar.value = bar.value+self.increment
902 self.master.after(100,self.update)
906 def configure_barre(self,nb):
907 """ Calcule l'incrément de progression de la barre en fonction
908 du nombre d'opérations à effectuer afin que le compteur
909 soit à 100% à la fin des opérations"""
910 self.increment = 100./nb
911 self.progress.update()
913 class Ask_Format_Fichier :
915 Cette classe permet de créer une fenêtre Toplevel dans laquelle
916 on propose le choix du format de fichier de commandes à ouvrir
918 def __init__(self,appli):
919 self.fenetre = Toplevel()
920 self.fenetre.configure(width = 250,height=150)
921 self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
922 self.fenetre.title("Choix du format du fichier de commandes")
923 # définition des frames
924 self.frame_texte = Frame(self.fenetre)
925 self.frame_radioboutons = Frame(self.fenetre)
926 self.frame_bouton_ok = Frame(self.fenetre)
927 self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
928 self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
929 self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
930 # définition de la zone texte et du scrollbar
931 zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
932 zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
933 # définition des radioboutons
934 Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
935 variable=appli.format_fichier,value='Aster').pack(anchor='n')
936 Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
937 variable=appli.format_fichier,value='Python').pack(anchor='n')
938 # création du bouton OK
939 Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
940 # centrage de la fenêtre
941 centerwindow(self.fenetre)
944 self.fenetre.destroy()
946 class BARRE_K2000(Toplevel):
947 def __init__(self,master=None,text = ""):
948 Toplevel.__init__(self,master,relief='groove')
949 self.master.iconify()
950 self.geometry("250x100+0+0")
951 self.protocol("WM_DELETE_WINDOW",self.quit)
952 # frame principale dans self (= Toplevel)
953 self.frame = Frame(self)
954 self.frame.place(relwidth=1,relheight=1)
955 # frame contenant le texte à afficher
956 self.frame_text = Frame(self.frame)
957 self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
958 # frame contenant le canvas de la barre
959 self.frame_canv = Frame(self.frame)
960 self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
961 # canvas dans lequel sera affichée la barre K2000
962 self.canvas = Canvas(self.frame_canv)
963 self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
964 # on affiche le texte et la barre
965 self.build_text(text)
967 #self.overrideredirect(1)
968 # on active la barre ...
969 self.master.after(1000,self.launch)
970 # on centre la fenêtre
974 def build_text(self,text):
976 Affichage de text dans frame_text
978 self.texte_var = StringVar()
979 self.texte_var.set(text)
980 Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
982 def build_batons(self):
984 Construit la suite de bâtons dans le canvas
990 for i in range(0,40):
991 id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
992 self.l_batons.append(id)
996 Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
1000 self.master.deiconify()
1002 if self.sens == 'D':
1003 self.black = self.black+1
1004 l_bat = self.l_batons[0:self.black+1]
1006 elif self.sens == 'G':
1007 self.black = self.black-1
1008 l_bat = self.l_batons[self.black:]
1012 if num_color < 10 : color = 'black'
1013 elif num_color > 90 : color = 'white'
1014 else: color = 'gray'+`num_color`
1015 self.canvas.itemconfigure(bat,fill=color)
1017 if self.black == len(self.l_batons) :
1019 if self.black == 0 and self.sens == 'G':self.sens = 'D'
1020 self.after(80,self.launch)
1022 def update_text(self,new_text):
1024 Remplace le texte affiché par new_text
1026 self.texte_var.set(new_text)
1031 class ListeChoixParGroupes(ListeChoix) :
1033 Cette classe est utilisée pour afficher une liste de commandes classées par
1034 groupes. L'utilisateur peut réaliser des actions de selection
1035 qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes
1037 def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[],
1038 active ='oui',filtre='non',titre=''):
1039 self.parent = parent
1041 self.liste_groupes = liste_groupes
1042 self.dict_groupes = dict_groupes
1044 self.selection = None
1045 self.liste_commandes = liste_commandes
1046 self.liste_marques = liste_marques
1047 self.arg_selected=''
1048 self.active = active
1050 self.filtre = filtre
1053 def affiche_liste(self):
1054 """ Affiche la liste dans la fenêtre"""
1056 self.MCbox.config(state=NORMAL)
1057 self.MCbox.delete(1.0,END)
1058 for grp in self.liste_groupes:
1059 # On itère sur les groupes
1060 if grp == "CACHE":continue
1061 liste_commandes=self.dict_groupes[grp]
1062 text="GROUPE<<<<<<<< "+grp+" "
1063 text=text+">"*max(0,30-len(text))
1064 label = Label(self.MCbox,
1066 fg = 'black',bg = 'gray95',justify = 'left')
1067 # On stocke la relation entre le nom de la commande et le label
1068 self.dico_labels[grp]=label
1069 liste_labels.append(label)
1070 self.MCbox.window_create(END,
1073 self.MCbox.insert(END,'\n')
1074 for cmd in liste_commandes:
1075 label = Label(self.MCbox,
1077 fg = 'black',bg = 'gray95',justify = 'left')
1078 # On stocke la relation entre le nom de la commande et le label
1079 self.dico_labels[cmd]=label
1080 self.MCbox.window_create(END,
1083 self.MCbox.insert(END,'\n')
1084 if self.active == 'oui':
1085 label.bind(self.liste_commandes[0][0],
1086 lambda e,s=self,c=self.liste_commandes[0][1],x=cmd,l=label : s.selectitem(x,l,c))
1087 label.bind(self.liste_commandes[1][0],
1088 lambda e,s=self,c=self.liste_commandes[1][1],x=cmd,l=label : s.deselectitem(l,x,c))
1089 label.bind(self.liste_commandes[2][0],
1090 lambda e,s=self,c=self.liste_commandes[2][1],x=cmd,l=label : s.chooseitem(x,l,c))
1092 for marque in self.liste_marques:
1094 self.markitem(liste_labels[marque])
1098 self.MCbox.config(state=DISABLED)
1099 self.selection = None
1101 def entry_changed(self,event=None):
1103 Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
1104 de l'entry et frappe <Return>
1106 if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
1107 filtre = self.entry.get()+"*"
1108 FILTRE = string.upper(filtre)
1110 # On cherche d'abord dans les noms de groupe
1111 # puis dans les noms de commande groupe par groupe
1113 for grp in self.liste_groupes:
1114 if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) :
1115 index = self.MCbox.index(self.dico_labels[grp])
1116 self.MCbox.see(index)
1117 # On ne selectionne pas le groupe
1118 #self.arg_selected = grp
1119 # On a trouve un groupe on arrete la recherche
1122 for grp in self.liste_groupes:
1123 for cmd in self.dict_groupes[grp] :
1124 if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) :
1125 self.highlightitem(self.dico_labels[cmd])
1126 index = self.MCbox.index(self.dico_labels[cmd])
1127 self.MCbox.see(index)
1128 self.arg_selected = cmd
1129 # On a trouve une commande on arrete la recherche