Salome HOME
PN Pour les formules
[tools/eficas.git] / Editeur / plusieursbasepanel.py
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.
9 #
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.
14 #
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.
18 #
19 #
20 # ======================================================================
21 # Modules Python
22 import string,types,os
23 from Tkinter import *
24 import Pmw
25 from copy import copy,deepcopy
26 import traceback
27
28 # Modules Eficas
29 import Objecttreeitem
30 import prefs
31 import panels
32 import images
33 from widgets import showinfo
34 from widgets import askopenfilename
35 from widgets import ListeChoix
36 from widgets import FenetreDeSelection
37 from widgets import FenetreDeParametre
38
39 from Noyau.N_CR import justify_text
40 from utils import substract_list
41 from plusieurspanel import PLUSIEURS_Panel
42
43
44
45 class PLUSIEURS_BASE_Panel(PLUSIEURS_Panel):
46   """
47   Classe définissant le panel associé aux mots-clés qui demandent
48   à l'utilisateur de donner une liste de valeurs qui ne sont pas
49   à choisir dans une liste discrètes et qui sont de type de base :
50   entier, réel, string,...
51   """
52   def makeValeurPage(self,page):
53       """
54       Crée la page de saisie d'une liste de valeurs à priori quelconques,
55       cad qui ne sont  pas à choisir dans une liste prédéfinie
56       """
57       # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
58       # et la liste des valeurs déjà affectées à l'objet courant
59       bulle_aide=self.get_bulle_aide()
60       objet_mc = self.node.item.get_definition()
61       aide = self.get_aide()
62       aide = justify_text(texte=aide)
63       min,max = self.node.item.GetMinMax()
64       l_valeurs = self.node.item.GetListeValeurs()
65
66       # création des frames globales
67       self.frame1 = Frame(page,relief='groove',bd=2)
68       self.frame2 = Frame(page)
69       self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.85)
70       self.frame2.place(relx=0.,rely=0.85,relwidth=1,relheight=0.15)
71       self.frame_right = Frame(self.frame1)
72       self.frame_right.place(relx=0.35,rely=0.,relwidth=0.65,relheight=1.)
73
74       # création des frames internes
75       self.frame_valeurs = Frame(self.frame1)
76       self.frame_valeurs.place(relx=0.02,rely=0.05,relwidth=0.35,relheight=0.95)
77       self.frame_boutons_fleches = Frame(self.frame_right)
78       self.frame_boutons_fleches.place(relx=0.,rely=0.2,relwidth=0.2,relheight=0.5)
79       self.frame_choix = Frame(self.frame_right)
80       self.frame_choix.place(relx=0.2,rely=0.2,relwidth=0.7,relheight=0.5)
81       self.frame_aide = Frame(self.frame_right)
82       self.frame_aide.place(relx=0.1,rely=0.7,relwidth=0.8,relheight=0.3)
83       self.frame_boutons = Frame(self.frame2)
84       self.frame_boutons.place(relx=0.35,rely=0.,relwidth=0.3,relheight=1.)
85       for fram in (self.frame1,self.frame2,self.frame_right,self.frame_valeurs,
86                  self.frame_boutons_fleches,self.frame_choix,self.frame_aide,self.frame_boutons):
87           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
88           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
89
90       # création des objets dans les frames
91       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
92                                  ("<Button-3>",self.deselectValeur),
93                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
94       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
95                                       titre="Valeur(s) actuelle(s)")
96
97       # Création de l'entry ou de la liste des SD
98       self.label = Label(self.frame_choix,text="Valeur :")
99       # PN : pour ajouter les validators
100       self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base)
101       self.label.place(relx=0.05,rely=0.5)
102
103       # Création d'un bouton "Importer ..." sur le panel.
104       bouton_valeurs_fichier = Button(self.frame_choix,
105                                       text="Importer ...",
106                                       command=self.select_in_file)
107       bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)
108       self.ajout_valeurs = None
109
110       # boutons Ajouter et Supprimer
111       bouton_add = Button(self.frame_boutons_fleches,
112                           image = images.get_image('arrow_left'),
113                           command = self.add_valeur_plusieurs_base)
114       bouton_sup = Button(self.frame_boutons_fleches,
115                           image = images.get_image('arrow_right'),
116                           command = self.sup_valeur_sans_into)
117       bouton_add.place(relx=0.3,rely=0.35)
118       bouton_sup.place(relx=0.3,rely=0.65)
119       # affichage de l'aide
120       self.frame_aide.update()
121       self.aide = Label(self.frame_aide,
122                         text = aide,
123                         justify='center',
124                         anchor='center',
125                         wraplength=int(self.frame_aide.winfo_width()*0.8))
126       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
127       self.Liste_valeurs.affiche_liste()
128       # boutons Accepter et Annuler
129       bouton_accepter = Button(self.frame_boutons,
130                                text='Valider',
131                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
132       bouton_annuler = Button(self.frame_boutons,
133                               text = 'Annuler',
134                               command = self.annule_modifs_valeur)
135       for but in (bouton_accepter,bouton_annuler):
136           but.pack(side='left',padx=5)
137             # traitement de la fenetre des parametres
138       if self.node.item.get_liste_param_possible() != [ ]:
139          txtparam=""
140          for param in self.node.item.get_liste_param_possible():
141             txtparam=txtparam+repr(param)+"\n"
142          self.fenetreparam=FenetreDeParametre( self,
143                                        self.node.item,
144                                        self.parent.appli,
145                                        txtparam)
146
147
148   def add_valeur_plusieurs_base(self,name=None):
149       if name != None :
150          valeur = name
151       else:
152          valeur,validite,commentaire=self.get_valeur()
153          if not validite :
154             self.parent.appli.affiche_infos(commentaire)
155             return
156
157       encorevalide=self.node.item.valide_item(valeur)
158       if encorevalide :
159          listecourante=self.Liste_valeurs.get_liste()
160          encorevalide=self.node.item.valide_liste_partielle(valeur,listecourante)
161          if not encorevalide : encorevalide = -1
162       self.add_valeur_sans_into(valeur,encorevalide)
163     
164   def select_in_file(self):
165       """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
166       nom_fichier = askopenfilename(title="Choix fichier :")
167
168       if not nom_fichier:
169           return
170
171       try:
172           f = open(nom_fichier, "rb")
173           selection_texte = f.read()
174           f.close()
175           self.ajout_valeurs = FenetreDeSelection(self, 
176                                                   self.node.item,
177                                                   self.parent.appli,
178                                                   titre="Sélection de valeurs",
179                                                   texte=selection_texte)
180       except:
181           traceback.print_exc()
182           showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
183           
184   def get_bulle_aide(self):
185       """
186       Retourne l'aide associée au panneau courant
187       """
188       return """Taper dans la boîte de saisie de droite la valeur que
189       vous voulez affecter au mot-clé simple.
190       - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
191       dans la liste des valeurs que vous voulez affecter au mot-clé simple
192       - Un clic sur une valeur de la liste la sélectionne
193       - Un clic sur la flèche droite ou un double-clic retire la valeur
194       sélectionnée de la liste
195       - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
196       au mot-clé simple
197       - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
198       depuis le dernier clic sur 'Valider'"""
199
200   def get_aide(self):
201       """
202       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
203       que saisit l'utilisateur
204       """
205       commentaire=""
206       mc = self.node.item.get_definition()
207       d_aides = { 'TXM' : 'chaînes de caractères',
208                   'R'   : 'réels',
209                   'I'   : 'entiers',
210                   'C'   : 'complexes'}
211       type = mc.type[0]
212       if not d_aides.has_key(type) : return 'Type de base inconnu'
213       if mc.min == mc.max:
214           commentaire="Une liste de "+d_aides[type]+" de longueur " + `mc.min`  + " est attendue"
215       else :
216           commentaire="Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
217
218       aideval=self.node.item.aide()
219       commentaire=commentaire +"\n"+aideval
220       return commentaire
221
222   def make_entry(self,frame,command):
223       """
224       Crée l'entry de saisie de la valeur souhaitée : distingue le
225       cas d'un complexe attendu, d'une autre valeur quelconque
226       """
227       if self.node.item.wait_complex():
228           self.typ_cplx=StringVar()
229           self.typ_cplx.set('RI')
230           rb1 = Radiobutton(frame, text='RI',variable=self.typ_cplx,value='RI')
231           rb2 = Radiobutton(frame, text='MP',variable=self.typ_cplx,value='MP')
232           self.entry1 = Pmw.EntryField(frame,validate='real')
233           self.entry2 = Pmw.EntryField(frame,validate='real')
234           rb1.place(relx=0.05,rely = 0.4)
235           rb2.place(relx=0.05,rely = 0.6)
236           self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus)
237           self.entry2.component('entry').bind("<Return>",lambda e,c=command:c())
238           self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
239           self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
240           self.entry1.focus()
241       else:
242           self.entry = Entry(frame,relief='sunken')
243           self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
244           self.entry.bind("<Return>",lambda e,c=command:c())
245           self.entry.focus()
246
247   def get_valeur(self):
248       """
249       Retourne la valeur saisie par l'utilisateur dans self.entry
250       """
251       if hasattr(self,'entry'):
252          # Traitement d'une entree unique
253          valeurentree = self.entry.get()
254          valeur,validite=self.node.item.eval_valeur(valeurentree)
255          if not validite :
256             commentaire = "impossible d'évaluer : %s " %`valeurentree`
257          else:
258             commentaire = ""
259          return valeur,validite,commentaire
260       else:
261          # Traitement d'une entree de type complexe
262          try:
263             valeur= (self.typ_cplx.get(),
264                      string.atof(self.entry1.get()),
265                      string.atof(self.entry2.get()))
266             return valeur,1,""
267          except:
268             #traceback.print_exc()
269             return None,0,"impossible d'évaluer la valeur d'entree"
270
271   def erase_valeur(self):
272       """
273       Efface la valeur donnée par l'utilisateur dans l'entry
274       """
275       if hasattr(self,'entry'):
276          self.entry.delete(0,END)
277       else:
278          self.typ_cplx.set('RI')
279          self.entry1.delete(0,END)
280          self.entry2.delete(0,END)
281
282         
283   def display_valeur(self,val=None):
284       """
285       Affiche la valeur passée en argument dans l'entry de saisie.
286       Par défaut affiche la valeur du mot-clé simple
287       """
288       if not val :
289           valeur = self.node.item.object.getval()
290       else:
291           valeur = val
292       if not valeur : return
293
294       if hasattr(self,'entry'):
295          # Traitement d'une entree unique
296          self.entry.delete(0,END)
297          self.entry.insert(0,str(valeur))
298       else:
299          # Traitement d'une entree de type complexe
300          typ_cplx,x1,x2=valeur
301          self.entry1.delete(0,END)
302          self.entry2.delete(0,END)
303          self.typ_cplx.set(typ_cplx)
304          self.entry1.setentry(x1)
305          self.entry2.setentry(x2)
306
307