Salome HOME
*** empty log message ***
[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.8)
81       self.frame_aide = Frame(self.frame_right)
82       self.frame_aide.place(relx=0.1,rely=0.8,relwidth=0.8,relheight=0.2)
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       # PN : pour ajouter les validators
99       self.label = Label(self.frame_choix,text="Valeur :")
100       self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base)
101       self.label.place(relx=0.05,rely=0.3)
102
103       # Création d'un bouton "Importer ..." et d'un bouton "Paramatres" 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.4,relwidth=0.6)
108       bouton_parametres = Button(self.frame_choix, text="Parametres", command=self.affiche_parametre)
109       bouton_parametres.place(relx=0.28,rely=0.6,relwidth=0.6)
110       self.ajout_valeurs = None
111
112       # boutons Ajouter et Supprimer
113       bouton_add = Button(self.frame_boutons_fleches,
114                           image = images.get_image('arrow_left'),
115                           command = self.add_valeur_plusieurs_base)
116       bouton_sup = Button(self.frame_boutons_fleches,
117                           image = images.get_image('arrow_right'),
118                           command = self.sup_valeur_sans_into)
119       bouton_add.place(relx=0.3,rely=0.35)
120       bouton_sup.place(relx=0.3,rely=0.65)
121       # affichage de l'aide
122       self.frame_aide.update()
123       self.aide = Label(self.frame_aide,
124                         text = aide,
125                         justify='center',
126                         anchor='center',
127                         wraplength=int(self.frame_aide.winfo_width()*0.8))
128       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
129       self.Liste_valeurs.affiche_liste()
130       if len(l_valeurs) > 0 :
131           liste_marque=l_valeurs[-1]
132           self.Liste_valeurs.surligne(liste_marque)
133       # boutons Accepter et Annuler
134       bouton_accepter = Button(self.frame_boutons,
135                                text='Valider',
136                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
137       bouton_annuler = Button(self.frame_boutons,
138                               text = 'Annuler',
139                               command = self.annule_modifs_valeur)
140       for but in (bouton_accepter,bouton_annuler):
141           but.pack(side='left',padx=5)
142
143   def affiche_parametre(self) :
144       if self.node.item.get_liste_param_possible() != [ ]:
145          txtparam=""
146          for param in self.node.item.get_liste_param_possible():
147             txtparam=txtparam+repr(param)+"\n"
148          if txtparam=="":
149             showerror("Aucun parametre ","Pas de parametre de ce type")
150          else :
151             try :
152                 self.self.fenetreparam.destroy()
153             except:
154                 pass
155             self.fenetreparam=FenetreDeParametre( self, self.node.item, self.parent.appli, txtparam)
156
157   def valid_valeur(self):
158       self.add_valeur_plusieurs_base()
159
160   def add_valeur_plusieurs_base(self,name=None):
161       if name != None :
162          valeur = name
163       else:
164          valeur,validite,commentaire=self.get_valeur()
165          if not validite :
166             self.parent.appli.affiche_infos(commentaire)
167             return
168
169       atraiter=[]
170       try :
171          for v in valeur:
172             atraiter.append(v)
173       except :
174          atraiter.append(valeur)
175
176       for valeur in atraiter :
177          encorevalide=self.node.item.valide_item(valeur)
178          if encorevalide :
179             listecourante=self.Liste_valeurs.get_liste()
180             encorevalide=self.node.item.valide_liste_partielle(valeur,listecourante)
181             if not encorevalide : encorevalide = -1
182          self.add_valeur_sans_into(valeur,encorevalide)
183     
184   def select_in_file(self):
185       """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
186       nom_fichier = askopenfilename(title="Choix fichier :")
187
188       if not nom_fichier:
189           return
190
191       try:
192           f = open(nom_fichier, "rb")
193           selection_texte = f.read()
194           f.close()
195           self.ajout_valeurs = FenetreDeSelection(self, 
196                                                   self.node.item,
197                                                   self.parent.appli,
198                                                   titre="Sélection de valeurs",
199                                                   texte=selection_texte)
200       except:
201           traceback.print_exc()
202           showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
203           
204   def get_bulle_aide(self):
205       """
206       Retourne l'aide associée au panneau courant
207       """
208       return """Taper dans la boîte de saisie de droite la valeur que
209       vous voulez affecter au mot-clé simple.
210       - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
211       dans la liste des valeurs que vous voulez affecter au mot-clé simple
212       - Un clic sur une valeur de la liste la sélectionne
213       - Un clic sur la flèche droite ou un double-clic retire la valeur
214       sélectionnée de la liste
215       - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
216       au mot-clé simple
217       - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
218       depuis le dernier clic sur 'Valider'"""
219
220   def get_aide(self):
221       """
222       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
223       que saisit l'utilisateur
224       """
225       commentaire=""
226       mc = self.node.item.get_definition()
227       d_aides = { 'TXM' : 'chaînes de caractères',
228                   'R'   : 'réels',
229                   'I'   : 'entiers',
230                   'C'   : 'complexes'}
231       type = mc.type[0]
232       if not d_aides.has_key(type) : return 'Type de base inconnu'
233       if mc.min == mc.max:
234           commentaire="Une liste de "+d_aides[type]+" de longueur " + `mc.min`  + " est attendue"
235       else :
236           commentaire="Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
237
238       aideval=self.node.item.aide()
239       commentaire=commentaire +"\n"+aideval
240       return commentaire
241
242   def make_entry(self,frame,command):
243       """
244       Crée l'entry de saisie de la valeur souhaitée : distingue le
245       cas d'un complexe attendu, d'une autre valeur quelconque
246       """
247       if self.node.item.wait_complex():
248           self.typ_cplx=StringVar()
249           self.typ_cplx.set('RI')
250           rb1 = Radiobutton(frame, text='RI',variable=self.typ_cplx,value='RI')
251           rb2 = Radiobutton(frame, text='MP',variable=self.typ_cplx,value='MP')
252           self.entry1 = Pmw.EntryField(frame,validate='real')
253           self.entry2 = Pmw.EntryField(frame,validate='real')
254           rb1.place(relx=0.05,rely = 0.4)
255           rb2.place(relx=0.05,rely = 0.6)
256           self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus)
257           self.entry2.component('entry').bind("<Return>",lambda e,c=command:c())
258           self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
259           self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
260           self.entry1.focus()
261       else:
262           self.entry = Entry(frame,relief='sunken')
263           self.entry.place(relx=0.28,rely=0.2,relwidth=0.6)
264           self.entry.bind("<Return>",lambda e,c=command:c())
265           self.entry.focus()
266
267   def get_valeur(self):
268       """
269       Retourne la valeur saisie par l'utilisateur dans self.entry
270       """
271       if hasattr(self,'entry'):
272          # Traitement d'une entree unique
273          valeurentree = self.entry.get()
274          if (valeurentree == None or valeurentree ==""):
275             return None,0,""
276          if (valeurentree[0] != "(") and (valeurentree.find(',') < len(valeurentree)):
277             valeurs=[]
278             for v in valeurentree.split(','):
279               vsimple,validite=self.node.item.eval_valeur(v)
280               if validite :
281                  valeurs.append(vsimple)
282               else:
283                  commentaire = "impossible d'évaluer : %s " %`valeurentree`
284                  break
285             valeur=valeurs
286          else: 
287             valeur,validite=self.node.item.eval_valeur(valeurentree)
288          if not validite :
289             commentaire = "impossible d'évaluer : %s " %`valeurentree`
290          else:
291             commentaire = ""
292          return valeur,validite,commentaire
293       else:
294          # Traitement d'une entree de type complexe
295          try:
296             valeur= (self.typ_cplx.get(),
297                      string.atof(self.entry1.get()),
298                      string.atof(self.entry2.get()))
299             return valeur,1,""
300          except:
301             #traceback.print_exc()
302             return None,0,"impossible d'évaluer la valeur d'entree"
303
304   def erase_valeur(self):
305       """
306       Efface la valeur donnée par l'utilisateur dans l'entry
307       """
308       if hasattr(self,'entry'):
309          self.entry.delete(0,END)
310       else:
311          self.typ_cplx.set('RI')
312          self.entry1.delete(0,END)
313          self.entry2.delete(0,END)
314
315         
316   def display_valeur(self,val=None):
317       """
318       Affiche la valeur passée en argument dans l'entry de saisie.
319       Par défaut affiche la valeur du mot-clé simple
320       """
321       if not val :
322           valeur = self.node.item.object.getval()
323       else:
324           valeur = val
325       if not valeur : return
326
327       if hasattr(self,'entry'):
328          # Traitement d'une entree unique
329          self.entry.delete(0,END)
330          self.entry.insert(0,str(valeur))
331       else:
332          # Traitement d'une entree de type complexe
333          typ_cplx,x1,x2=valeur
334          self.entry1.delete(0,END)
335          self.entry2.delete(0,END)
336          self.typ_cplx.set(typ_cplx)
337          self.entry1.setentry(x1)
338          self.entry2.setentry(x2)
339
340