]> SALOME platform Git repositories - tools/eficas.git/blob - Editeur/widgets.py
Salome HOME
Version Aster 6.3.14
[tools/eficas.git] / Editeur / widgets.py
1 #@ MODIF widgets Editeur  DATE 05/09/2001   AUTEUR DURAND C.DURAND 
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2001  EDF R&D                  WWW.CODE-ASTER.ORG
5 #              SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND
6 #              REDISTRIBUTION OF THIS FILE.
7 # ======================================================================
8 # ----------------------------------------------------------
9 #   Cette classe sert à définir les widgets utilisés par
10 #          EFICAS
11 # ----------------------------------------------------------
12
13 from Tkinter import *
14 import Pmw
15 import os,sys,re,string
16 import types,fnmatch
17 from tkFileDialog import *
18 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
19
20 import fontes
21 import prefs
22 from utils import save_in_file
23 from centerwindow import centerwindow
24
25 from Noyau.N_utils import repr_float
26     
27 class Fenetre :
28     """ Cette classe permet de créer une fenêtre Toplevel dans laquelle
29         on peut afficher un texte et qui permet de le sauver"""
30     def __init__(self,appli,titre="",texte=""):
31         self.appli=appli
32         self.fenetre = Toplevel()
33         self.fenetre.configure(width = 800,height=500)
34         self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
35         self.fenetre.title("Visualisation du "+titre)
36         self.texte = string.replace(texte,'\r\n','\n')
37         self.titre = titre
38         fonte=fontes.standardcourier10
39         # définition des frames
40         self.frame_texte = Frame(self.fenetre)
41         self.frame_boutons = Frame(self.fenetre)
42         self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.9)
43         self.frame_boutons.place(relheight=0.1,relx=0,rely=0.9,relwidth=1.)
44         # définition de la zone texte et du scrollbar
45         self.zone_texte = Text(self.frame_texte,font=fonte)
46         self.zone_texte.bind("<Key-Prior>", self.page_up)
47         self.zone_texte.bind("<Key-Next>", self.page_down)
48         self.zone_texte.bind("<Key-Up>", self.unit_up)
49         self.zone_texte.bind("<Key-Down>", self.unit_down)
50         self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview)
51         #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview)
52         self.scroll_v.pack(side='right',fill ='y')
53         #self.scroll_h.pack(side='bottom',fill ='x')
54         self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
55         self.zone_texte.configure(yscrollcommand=self.scroll_v.set)
56         # définition des boutons
57         self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit)
58         self.but_save = Button(self.frame_boutons,text = "sauver",command = self.save)
59         self.but_quit.place(relx=0.4,rely=0.5,anchor='center')
60         self.but_save.place(relx=0.6,rely=0.5,anchor='center')
61         # affichage du texte
62         self.affiche_texte(self.texte)
63         centerwindow(self.fenetre)
64
65     def page_up(self,event):
66         event.widget.yview_scroll(-1, "page")
67     def page_down(self,event):
68         event.widget.yview_scroll(1, "page")
69     def unit_up(self,event):
70         event.widget.yview_scroll(-1, "unit")
71     def unit_down(self,event):
72         event.widget.yview_scroll(1, "unit")
73
74     def wait(self):
75         self.fenetre.grab_set()
76         self.fenetre.wait_window(self.fenetre)
77
78     def quit(self):
79         self.fenetre.destroy()
80
81     def efface_scroll(self):
82         """ Efface le scroll lorsqu'il n'est pas nécessaire : ne marche pas"""
83         self.scroll_v.pack_forget()
84         #self.scroll_h.pack_forget()
85
86     def affiche_texte(self,texte):
87         """ Affiche le texte dans la fenêtre """
88         if texte != "" :
89             self.zone_texte.insert(END,texte)
90             try:
91                 self.fenetre.update_idletasks()
92                 x0,y0,x1,y1 = self.zone_texte.bbox(END)
93                 if (y1-y0) < 300 : self.efface_scroll()
94             except:
95                 pass
96
97     def save(self):
98         """ Permet de sauvegarder le texte dans un fichier dont on a demandé le nom
99         à l'utilisateur """
100         file = asksaveasfilename(defaultextension = '.comm',
101                                initialdir = self.appli.CONFIGURATION.rep_user,
102                                title="Sauvegarde du "+self.titre)
103         if file != '':
104             if not save_in_file(file,self.texte) :
105                 showerror("Sauvegarde impossible",
106                        "Impossible de sauvegarder le texte dans le fichier spécifié\n"+
107                           "Vérifiez les droits d'écriture")
108             else:
109                 showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file)
110
111 class FenetreDeSelection(Fenetre):
112     """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée.\r
113         Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé.\r
114     """\r
115     def __init__(self,panel,item,appli,titre="",texte=""):\r
116         Fenetre.__init__(self,appli,titre=titre,texte=texte)\r
117         self.fenetre.configure(width = 320,height=400)\r
118         centerwindow(self.fenetre)
119         self.panel = panel
120         self.item = item
121         self.fenetre.title(titre)
122         self.but_save.configure(text="Ajouter",command=self.traite_selection)\r
123         # séparateur par défaut\r
124         self.separateur = ";"\r
125         # création de la zone de saisie du séparateur\r
126         l_separateurs_autorises = self.get_separateurs_autorises()\r
127         self.choix_sep = Pmw.ComboBox(self.frame_boutons,\r
128                                       label_text = "Séparateur :",\r
129                                       labelpos = 'w',\r
130                                       listheight = 100,\r
131                                       selectioncommand = self.choose_separateur,\r
132                                       scrolledlist_items = l_separateurs_autorises)\r
133         self.choix_sep.component('entry').configure(width=6)\r
134         self.choix_sep.place(relx=0.01,rely=0.5,anchor='w')\r
135         self.choix_sep.selectitem(self.separateur)\r
136         # Replacement\r
137         self.but_quit.place_forget()\r
138         self.but_save.place_forget()\r
139         self.but_save.place(relx=0.6,rely=0.5,anchor='center')\r
140         self.but_quit.place(relx=0.8,rely=0.5,anchor='center')\r
141 \r
142     def get_separateurs_autorises(self):\r
143         """\r
144         Retourne la liste des séparateurs autorisés\r
145         """\r
146         return ['espace',';',',']\r
147 \r
148     def choose_separateur(self,nom_sep):\r
149         """\r
150         Affecte à self.separateur le caractère séparateur correspondant à nom_sep\r
151         """\r
152         if nom_sep == 'espace' :\r
153             self.separateur = ' '\r
154         else:\r
155             self.separateur = nom_sep\r
156         \r
157     def traite_selection(self):\r
158         """ Cette méthode effectue tous les traitements nécessaires pour vérifier\r
159             et affecter la liste de valeurs à l'objet réprésenté par self.item\r
160         """\r
161         # Récupère la liste des chaines de caractères de la zone sélectionnée\r
162         message,liste = self.recupere_liste()\r
163         if self.test_probleme(message,"Sélectionnez des données") == 0:\r
164             return\r
165         # Vérifie que le nombre de données est dans les limites attendues\r
166         message = self.verif_liste(liste)\r
167         if self.test_probleme(message,"Vérifiez le nombre de données") == 0:\r
168             return\r
169         # Crée une liste de valeurs du type attendu\r
170         message,liste_valeurs = self.creation_liste_valeurs(liste)\r
171         if self.test_probleme(message,"Vérifiez le type des données") == 0:\r
172             return\r
173         # Vérifie que chaque valeur est dans le domaine exigé\r
174         message = self.verif_valeurs(liste_valeurs)\r
175         if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0:\r
176             return\r
177         # Ajoute les valeurs dans la liste de valeurs du mot-clé\r
178         self.ajouter_valeurs(liste_valeurs)\r
179         self.appli.affiche_infos("Liste de valeurs acceptée")\r
180 \r
181     def test_probleme(self, message, message_eficas):\r
182         """ Cette méthode affiche un message d'erreur si message != ''\r
183             et retourne 0, sinon retourne 1 sans rien afficher.\r
184         """\r
185         if message != "":\r
186             showinfo("Problème",message)\r
187             self.fenetre.tkraise()\r
188             self.appli.affiche_infos(message_eficas)\r
189             return 0\r
190         else:\r
191             return 1\r
192 \r
193     def recupere_liste(self):\r
194         """ Cette méthode récupère le texte de la zone sélectionnée, construit et\r
195             retourne une liste avec les chaines qui se trouvent entre les séparateurs.\r
196             S'il n'y a pas de données selectionnées, elle retourne un message d'erreur\r
197             et une liste vide.\r
198         """\r
199         message = ""\r
200         try:\r
201             selection=self.fenetre.selection_get()\r
202         except:\r
203             message = "Pas de donnée sélectionnée"\r
204             return message,None\r
205         # les retours chariots doivent être interprétés comme des séparateurs\r
206         selection = string.replace(selection,'\n',self.separateur)\r
207         # on splitte la sélection suivant le caractère séparateur\r
208         liste_chaines = string.split(selection,self.separateur)\r
209         l_chaines = []\r
210         for chaine in liste_chaines:\r
211             chaine = string.strip(chaine)\r
212             if chaine != '' : l_chaines.append(chaine)\r
213         return message,l_chaines\r
214 \r
215     def verif_liste(self, liste):\r
216         """ Cette méthode effectue des tests sur le nombre d'éléments de la liste\r
217             et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur\r
218             correspondant.\r
219         """\r
220         message = ""\r
221         # nombre d'éléments sélectionnés\r
222         nombre_elements = len(liste)\r
223         # nombre d'éléments déja dans la liste du panel\r
224         nombre_in_liste = len(self.panel.Liste_valeurs.get_liste())\r
225         multiplicite = self.item.GetMultiplicite()\r
226         if (nombre_elements % multiplicite) != 0:\r
227             message = "Vous devez sélectionner "+str(multiplicite)+" * n données"\r
228             return message\r
229         nombre_valeurs = nombre_elements / multiplicite\r
230         cardinalite = self.item.GetMinMax()\r
231         if nombre_valeurs < cardinalite[0]:\r
232             message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs"\r
233             return message\r
234         if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste):\r
235             message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs"\r
236             return message\r
237 \r
238         return message\r
239 \r
240     def creation_liste_valeurs(self, liste):\r
241         """ Cette méthode crée et retourne une liste de valeurs du type attendu\r
242             par le mot-clé. La liste de valeurs est créée à partir de la liste\r
243             de chaines de caractères transmise.\r
244         """\r
245         type_attendu = self.item.GetType()[0]\r
246         if type_attendu == 'R':\r
247             return self.convertir(liste, f_conversion= float)\r
248         elif type_attendu == 'I':\r
249             return self.convertir(liste, f_conversion= int)\r
250         elif type_attendu == 'TXM':\r
251             return self.convertir(liste)\r
252         else:\r
253             message = "Seuls les entiers, les réels et les chaines de caractères sont convertis"\r
254             return message,None\r
255 \r
256     def convertir(self, liste, f_conversion=None):\r
257         """ Cette méthode essaie de convertir les éléments de la liste avec la\r
258             fonction f_conversion si elle existe, et retourne la liste des\r
259             éléments dans le type voulu en cas de succès, sinon retourne None.\r
260         """\r
261         liste_valeurs = []\r
262         message = ""\r
263         for chaine in liste:\r
264             if f_conversion:\r
265                 try:\r
266                     liste_valeurs.append(f_conversion(chaine))\r
267                 except:\r
268                     message = "Impossible de convertir "+chaine+" dans le type attendu"\r
269                     return message,None\r
270             else:\r
271                 liste_valeurs.append(chaine)\r
272         return message,liste_valeurs\r
273 \r
274     def verif_valeurs(self, liste_valeurs):\r
275         """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque\r
276             élément est dans le domaine voulu.\r
277         """\r
278         message = ""\r
279         for valeur in liste_valeurs:\r
280             test = self.item.IsInIntervalle(valeur)\r
281             if test == 0:\r
282                 intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1])\r
283                 message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]"\r
284                 return message\r
285         return message\r
286 \r
287     def ajouter_valeurs(self, liste_valeurs):\r
288         """ Cette méthode ajoute les nouvelles valeurs à la liste existante."""\r
289         liste = self.panel.Liste_valeurs.get_liste()\r
290         liste.extend(liste_valeurs)\r
291         self.panel.Liste_valeurs.put_liste(liste)
292
293 class Formulaire:
294     """\r
295     Cette classe permet de créer une boîte Dialog dans laquelle
296     on affiche un formulaire à remplir par l'utilisateur\r
297     """
298     def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None):\r
299         if items in ((),[]) : return
300         self.items = items
301         self.titre = titre
302         self.texte = texte
303         self.fen_pere = fen_pere
304         self.obj_pere = obj_pere
305         self.mode= mode
306         self.command = commande
307         self.display()
308
309     def display(self):\r
310         self.init_validateurs()
311         self.init_fenetre()
312         self.init_texte()
313         self.init_items_formulaire()
314         self.fenetre.activate(geometry='centerscreenalways')
315 \r
316     def init_validateurs(self):\r
317         """\r
318         Crée le dictionnaire des validateurs des objets reconnus par le formulaire\r
319         """\r
320         self.d_validateurs = {}\r
321         self.d_validateurs['rep']  = self.repvalidator\r
322         self.d_validateurs['file'] = self.filevalidator\r
323         self.d_validateurs['cata']= self.catavalidator\r
324         
325     def init_fenetre(self):\r
326         """\r
327         Crée la fenêtre Dialog\r
328         """
329         if self.mode == 'query':
330             buttons=('Valider','Annuler')
331             defaultbutton = 'Valider'
332         elif self.mode == 'display':
333             if self.command :
334                 buttons=(self.command[0],'OK')
335                 defaultbutton = 'OK'
336             else:
337                 buttons=('OK')
338                 defaultbutton = 'OK'
339         self.fenetre = Pmw.Dialog(self.fen_pere,
340                                   buttons=buttons,
341                                   defaultbutton = defaultbutton,
342                                   title = self.titre,
343                                   command = self.execute)\r
344         self.fenetre.withdraw()
345         
346     def init_texte(self):\r
347         """\r
348         Crée le label qui affiche le texte à l'intérieur du panneau\r
349         """
350         fonte=fontes.standard\r
351         fr_texte = Frame(self.fenetre.interior(),height=60)\r
352         fr_texte.pack(side='top',fill='x',expand=1)
353         Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center')
354 \r
355     def init_items_formulaire(self):\r
356         """\r
357         Crée et affiche les items dans la boîte de dialogue\r
358         """\r
359         self.radiobut = 0\r
360         self.widgets = []\r
361         self.item_widgets = {}\r
362         length_maxi = 0\r
363         for item in self.items:
364             if len(item[0])>length_maxi : length_maxi = len(item[0])\r
365         window = self.fenetre.interior()\r
366         for item in self.items :\r
367             label,nature,nom_var,defaut = item\r
368             # création de la frame\r
369             fr_item = Frame(window,height=40,width=700)\r
370             fr_item.pack(side='top',fill='x',expand=1)\r
371             # création du label\r
372             Label(fr_item,text = label).place(relx=0.05,rely=0.4)\r
373             if nature in ('rep','file','cata'):
374                 # création de l'entry\r
375                 e_item = Entry(fr_item) \r
376                 e_item.place(relx=0.5,rely=0.4,relwidth=0.45)\r
377                 self.widgets.append(e_item)\r
378                 self.item_widgets[item] = e_item\r
379                 if defaut : e_item.insert(0,str(defaut))\r
380             elif nature == 'YesNo':\r
381                 # création de la StringVar\r
382                 var = StringVar()\r
383                 setattr(self,'item_'+nom_var,var)\r
384                 var.set(defaut)\r
385                 # création du radiobouton\r
386                 rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI')\r
387                 rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON')\r
388                 rb1.place(relx=0.65,rely=0.5,anchor='center')\r
389                 rb2.place(relx=0.80,rely=0.5,anchor='center')\r
390                 self.widgets.append((rb1,rb2))\r
391                 self.item_widgets[item] = var\r
392         # détermination de la méthode à appliquer sur les boutons\r
393         if self.mode == 'query':\r
394             function = self.active\r
395         elif self.mode == 'display':\r
396             function = self.inactive\r
397         else:\r
398             return\r
399         # on applique la méthode sur les boutons (activation ou désactivation)    \r
400         for widget in self.widgets :\r
401             if type(widget) == types.TupleType:\r
402                 for widg in widget :\r
403                     apply(function,(widg,),{})\r
404             else:\r
405                 apply(function,(widget,),{})\r
406 \r
407     def active(self,widget):\r
408         """\r
409         Active le widget passé en argument\r
410         """\r
411         widget.configure(state='normal',bg='white')\r
412 \r
413     def inactive(self,widget):\r
414         """\r
415         Inactive le widget passé en argument\r
416         """\r
417         if not isinstance(widget,Radiobutton) :\r
418             widget.configure(state='disabled',bg='gray95')\r
419         else :\r
420             widget.configure(state='disabled')\r
421 \r
422 # --------------------------------------------------------------------------------\r
423 #       Validateurs des noms de répertoire, de fichiers et de catalogues\r
424 # --------------------------------------------------------------------------------\r
425
426     def repvalidator(self,text):
427         """\r
428         Teste si text peut faire référence à un répertoire ou non\r
429         Retourne 1 si valide, 0 sinon\r
430         """\r
431         return os.path.isdir(text),'Répertoire introuvable : %s' %text
432
433     def filevalidator(self,text):
434         """\r
435         Teste si text peut faire référence à un fichier ou non\r
436         Retourne 1 si valide, 0 sinon\r
437         """\r
438         return os.path.isfile(text),'Fichier introuvable : %s' %text
439 \r
440     def catavalidator(self,text):\r
441         """\r
442         Teste si  text est un chemin d'accès valide à un catalogue\r
443         Retourne 1 si valide, 0 sinon\r
444         """\r
445         return os.path.isfile(text),"Catalogue introuvable : %s" %text\r
446 \r
447 # --------------------------------------------------------------------------------\r
448 #       Méthodes callbacks des boutons et de fin\r
449 # --------------------------------------------------------------------------------\r
450         
451     def execute(self,txt):\r
452         """\r
453         Cette commande est activée à chaque clic sur un bouton.\r
454         Redirige l'action sur la bonne méthode en fonction du bouton activé\r
455         """
456         if txt == 'Valider':
457             self.fini()
458         elif txt in ('OK','Annuler'):
459             self.quit()
460         elif txt == 'Modifier':
461             self.resultat = apply(self.command[1],(),{})
462             self.fenetre.destroy()
463         else :
464             print "Nom de bouton inconnu"
465             self.quit()
466
467     def fini(self):\r
468         """\r
469         Commande qui termine le panneau et sauvegarde les nouvelles options\r
470         dans l'objet resultat (dictionnaire)\r
471         """
472         dico={}
473         for item,widget in self.item_widgets.items():\r
474             nom_var = item[2]\r
475             type_var = item[1]
476             valeur = widget.get()\r
477             if self.d_validateurs.has_key(type_var):\r
478                 test = self.d_validateurs[type_var](valeur)\r
479                 if not test :\r
480                     # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode\r
481                     # sans tuer la fenêtre bien sûr\r
482                     widget.selection_range(0,END)\r
483                     return
484             dico[nom_var] = valeur
485         self.fenetre.destroy()    
486         self.resultat=dico\r
487         
488     def quit(self):
489         self.fenetre.destroy()
490         self.resultat=None
491         
492 class ListeChoix :
493     """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre
494         en passant les commandes à lancer suivant différents bindings """
495     def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''):
496         self.parent = parent
497         self.page = page
498         self.liste = liste
499         self.dico_labels={}
500         self.selection = None
501         self.liste_commandes = liste_commandes
502         self.liste_marques = liste_marques
503         self.arg_selected=''
504         self.active = active
505         self.titre = titre
506         self.filtre = filtre
507         self.init()
508
509     def init(self):        
510         self.make_label_titre()
511         self.make_entry_filtre()
512         self.make_text_box()
513         try:
514             self.entry.component('entry').focus()
515         except:
516             pass
517
518     def make_label_titre(self):
519         """ Crée le label correspondant au titre """
520         if self.titre == '' : return
521         fonte_titre = fontes.standard_gras_souligne
522         self.label = Label(self.page,
523                            text = self.titre,
524                            font = fonte_titre)
525         self.label.pack(side='top',pady=2)
526         
527     def make_entry_filtre(self):
528         """ Crée l'entry permettant à l'utilisateur d'entrer un filtre de sélection dans la liste """
529         if self.filtre != 'oui' : return
530         self.entry = Pmw.EntryField(self.page,labelpos='w',
531                                     label_text="Filtre :",
532                                     command=self.entry_changed)
533         self.entry.pack(side='top',pady=2)
534         
535     def make_text_box(self):
536         """ Crée la fenêtre texte dans laquelle sera affichée la liste """
537         self.MCbox = Text (self.page,relief='sunken',bg='gray95',bd=2)
538         self.MCscroll = Scrollbar (self.page,command = self.MCbox.yview)
539         self.MCscroll.pack(side='right',fill ='y',pady=2)
540         self.MCbox.pack(fill='y',expand=1,padx=2,pady=2)
541         self.MCbox.configure(yscrollcommand=self.MCscroll.set)
542
543     def affiche_liste(self):
544         """ Affiche la liste dans la fenêtre"""
545         i=0
546         self.MCbox.config(state=NORMAL)
547         self.MCbox.delete(1.0,END)
548         for objet in self.liste :
549           if type(objet) == types.InstanceType:
550               try:
551                   mot = objet.nom
552               except:
553                   mot = str(objet)
554           elif type(objet) in (types.StringType,types.IntType):
555               mot = objet
556           elif type(objet) == types.FloatType :
557               mot = repr_float(objet)
558           else:
559               mot=`objet`
560           label = Label(self.MCbox,
561                         text = mot,
562                         fg = 'black',bg = 'gray95',justify = 'left')
563           self.dico_labels[mot]=label
564           self.MCbox.window_create(END,
565                                    window=label,
566                                    stretch = 1)
567           self.MCbox.insert(END,'\n')
568           if self.active == 'oui':
569               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))
570               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))
571               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))
572           try :
573               self.liste_marques.index(i)
574               self.markitem(label)
575           except:
576               pass
577           i=i+1
578         self.MCbox.config(state=DISABLED)
579         self.selection = None
580
581     def chooseitem(self,mot,label,commande):
582         """ Active la méthode de choix passée en argument"""
583         commande(mot)
584         
585     def selectitem(self,mot,label,commande) :
586         """ Met l'item sélectionné (représenté par son label) en surbrillance
587             et lance la commande associée au double-clic"""
588         if self.selection != None :
589             self.deselectitem(self.selection[1],self.selection[0],self.selection[2],)
590         self.highlightitem(label)
591         self.selection = (mot,label,commande)
592         self.arg_selected = mot
593         commande(mot)
594
595     def highlightitem(self,label) :
596         """ Met l'item représenté par son label en surbrillance """
597         label.configure(bg='#00008b',fg='white')
598         
599     def markitem(self,label):
600         """ Met l'item (représenté par son label) en rouge """
601         label.configure(bg='gray95',fg='red')
602         
603     def deselectitem(self,label,mot='',commande=None) :
604         """ Remet l'item (représenté par son label) en noir"""
605         label.configure(bg='gray95',fg='black')
606         self.arg_selected = ''
607         if commande != None : commande(mot)
608
609     def entry_changed(self,event=None):
610         """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu
611         de l'entry et frappe <Return>"""
612         if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected])
613         filtre = self.entry.get()+"*"
614         FILTRE = string.upper(filtre)
615         for arg in self.liste :
616             if fnmatch.fnmatch(arg,filtre) or fnmatch.fnmatch(arg,FILTRE) :
617                 self.highlightitem(self.dico_labels[arg])
618                 index = self.MCbox.index(self.dico_labels[arg])
619                 self.MCbox.see(index)
620                 self.arg_selected = arg
621                 break
622
623     def get_liste_old(self):
624         return self.liste
625
626     def get_liste(self):
627         l=[]
628         for val in self.liste:
629             try:
630                 val = eval(val)
631                 l.append(val)
632             except:
633                 l.append(val)
634         return l
635     
636     def put_liste(self,liste):
637         self.liste = liste
638         self.affiche_liste()
639         
640 class Affichage :
641   """ Cette classe permet d'afficher au lancement d'EFICAS le message
642       d'attente et la barre de progression"""
643   def __init__(self,master,message,barre ='oui'):
644       from Tools.foztools.foztools import Slider
645       fonte=fontes.standard12_gras
646       self.master=master
647       self.frame = Frame(self.master)
648       self.frame.pack(expand=1,fill='both')
649       self.mess = Label(self.frame,text=message,justify='center',
650                         bd=2,relief='groove',font=fonte)
651       self.mess.pack(in_ = self.frame,side='top',expand=1,fill='both')
652       self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
653                              fillColor='#00008b',width=200,height=30,
654                              background='white',labelColor='red')
655       if barre == 'oui':
656           self.progress.frame.pack(in_=self.frame,side='top')
657       self.master.update()
658       if barre == 'oui':
659           self.progress.frame.after(1000,self.update)
660
661   def configure(self,**options):
662       if options.has_key('message'):
663           self.mess.configure(text=options['message'])
664       if options.has_key('barre'):
665           if options['barre'] == 'oui' :
666               self.progress.frame.pack(in_=self.frame,side='top')
667           elif options['barre'] == 'non' :
668               self.progress.frame.pack_forget()
669       self.master.update_idletasks()
670       
671   def quit(self):
672       self.frame.destroy()
673       self.master.update()
674
675   def update(self,event=None):
676       """ Permet de faire avancer la barre de progression """
677       try :
678           bar=self.progress
679           bar.value = bar.value+self.increment
680           bar.update()
681           self.master.after(100,self.update)
682       except:
683           pass
684
685   def configure_barre(self,nb):
686       """ Calcule l'incrément de progression de la barre en fonction
687           du nombre d'opérations à effectuer afin que le compteur
688           soit à 100% à la fin des opérations"""
689       self.increment = 100./nb
690       self.progress.update()
691
692 class Ask_Format_Fichier :
693     """\r
694     Cette classe permet de créer une fenêtre Toplevel dans laquelle
695     on propose le choix du format de fichier de commandes à ouvrir\r
696     """
697     def __init__(self,appli):
698         self.fenetre = Toplevel()
699         self.fenetre.configure(width = 250,height=150)
700         self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
701         self.fenetre.title("Choix du format du fichier de commandes")
702         # définition des frames
703         self.frame_texte = Frame(self.fenetre)
704         self.frame_radioboutons = Frame(self.fenetre)
705         self.frame_bouton_ok = Frame(self.fenetre)
706         self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.3)
707         self.frame_radioboutons.place(relheight=0.5,relx=0,rely=0.3,relwidth=1.)
708         self.frame_bouton_ok.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.)
709         # définition de la zone texte et du scrollbar
710         zone_texte = Label(self.frame_texte,text = "Format du fichier à ouvrir :")
711         zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10)
712         # définition des radioboutons
713         Radiobutton(self.frame_radioboutons,text='Format Aster (Code_Aster --> v5)',
714                     variable=appli.format_fichier,value='Aster').pack(anchor='n')
715         Radiobutton(self.frame_radioboutons,text='Format Python (Code_Aster v6-->)',
716                     variable=appli.format_fichier,value='Python').pack(anchor='n')
717         # création du bouton OK
718         Button(self.frame_bouton_ok,text='OK',command=self.quit).pack(anchor='n')
719         # centrage de la fenêtre
720         centerwindow(self.fenetre)
721
722     def quit(self):
723         self.fenetre.destroy()
724
725 class BARRE_K2000(Toplevel):
726     def __init__(self,master=None,text = ""):
727         Toplevel.__init__(self,master,relief='groove')
728         self.master.iconify()
729         self.geometry("250x100+0+0")
730         self.protocol("WM_DELETE_WINDOW",self.quit)
731         # frame principale dans self (= Toplevel)
732         self.frame = Frame(self)
733         self.frame.place(relwidth=1,relheight=1)
734         # frame contenant le texte à afficher 
735         self.frame_text = Frame(self.frame)
736         self.frame_text.place(relwidth=1,relheight=0.75,rely=0)
737         # frame contenant le canvas de la barre
738         self.frame_canv = Frame(self.frame)
739         self.frame_canv.place(relwidth=1,relheight=0.25,rely=0.75)
740         # canvas dans lequel sera affichée la barre K2000
741         self.canvas = Canvas(self.frame_canv)
742         self.canvas.place(relx=0.5,rely=0.5,relheight=0.8,relwidth=0.8,anchor='center')
743         # on affiche le texte et la barre
744         self.build_text(text)
745         self.build_batons()
746         #self.overrideredirect(1)
747         # on active la barre ...
748         self.master.after(1000,self.launch)
749         # on centre la fenêtre
750         centerwindow(self)
751         self.focus()
752
753     def build_text(self,text):
754         """
755         Affichage de text dans frame_text
756         """
757         self.texte_var = StringVar()
758         self.texte_var.set(text)
759         Label(self.frame_text,textvariable=self.texte_var).place(relx=0.5,rely=0.5,anchor='center')
760         
761     def build_batons(self):
762         """
763         Construit la suite de bâtons dans le canvas
764         """
765         self.l_batons=[]
766         self.black = -1
767         self.sens = 'D'
768         self.quit = 0
769         for i in range(0,40):
770             id = self.canvas.create_rectangle(i*5,0,(i+1)*5,20,fill='gray90',outline='')
771             self.l_batons.append(id)
772
773     def launch(self):
774         """
775         Active la barre K2000 en affichant les bâtons avec des couleurs en dégradé
776         """
777         if self.quit == 1 :
778             self.destroy()
779             self.master.deiconify()
780             return
781         if self.sens == 'D':
782             self.black = self.black+1
783             l_bat = self.l_batons[0:self.black+1]
784             l_bat.reverse()
785         elif self.sens == 'G':
786             self.black = self.black-1
787             l_bat = self.l_batons[self.black:]
788         i=0
789         for bat in l_bat :
790             num_color = 5+i*10
791             if num_color < 10 : color = 'black'
792             elif num_color > 90 : color = 'white'
793             else: color = 'gray'+`num_color`
794             self.canvas.itemconfigure(bat,fill=color)
795             i=i+1
796         if self.black == len(self.l_batons) :
797             self.sens = 'G'
798         if self.black == 0 and self.sens == 'G':self.sens = 'D'
799         self.after(80,self.launch)
800
801     def update_text(self,new_text):
802         """
803         Remplace le texte affiché par new_text
804         """
805         self.texte_var.set(new_text)
806         
807     def quit(self):
808         self.quit = 1