Salome HOME
pb d accent. on les enleve en français
[tools/eficas.git] / Ihm / I_FORM_ETAPE.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 """
21 """
22 import string,traceback
23
24 from Extensions.i18n import tr
25 from I_MACRO_ETAPE import MACRO_ETAPE
26 from Extensions import interpreteur_formule
27 from Editeur import analyse_catalogue
28
29 analyse_catalogue.l_noms_commandes.append('FORM') # déclare le nom FORM à l'analyseur de catalogue
30
31
32 class FORM_ETAPE(MACRO_ETAPE):
33
34     interpreteur = interpreteur_formule.Interpreteur_Formule
35
36     def McBuild(self):
37         self.mc_liste=self.build_mc()
38         # on crée la liste des types autorisés (liste des noms de mots-clés
39         # simples dans le catalogue de FORMULE)
40         self.l_types_autorises = self.definition.entites.keys()
41         # en plus de la construction traditionnelle des fils de self
42         # il faut pour les FORMULE décortiquer l'expression ...
43         self.type_retourne,self.arguments,self.corps = self.analyse_formule()
44
45
46     def analyse_formule(self):
47         """
48         Cette méthode décortique l'expression de la FORMULE.
49         Elle retourne 3 valeurs:
50             - le type retourné par la FORMULE
51             - les arguments de la FORMULE
52             - le corps de la FORMULE, cad son expression
53         """
54         if len(self.mc_liste) == 0:
55             # pas de fils pour self --> la FORMULE est incomplète
56             return None,None,None
57         type_retourne="REEL"
58         if len(self.mc_liste) > 0:
59            child = self.mc_liste[0] # child est un MCSIMP 
60            corps = child.getval()
61         else:
62            corps = None
63         if len(self.mc_liste) > 1:
64            child = self.mc_liste[1]
65            l_args= child.getval()
66         else :
67            l_args=None
68         return type_retourne,l_args,corps
69
70     def get_nom(self):
71         """
72         Retourne le nom de la FORMULE, cad le nom de la SD si elle existe,
73         la string vide sinon
74         """
75         if self.sd :
76             return self.sd.get_name()
77         else:
78             return ''
79
80     def get_formule(self):
81         """
82         Retourne un tuple décrivant la formule :
83         (nom,type_retourne,arguments,corps)
84         """
85         t,a,c = self.analyse_formule()
86         n = self.get_nom()
87         return (n,t,a,c)
88
89     def verif_arguments(self,arguments = None):
90         """
91         Vérifie si les arguments passés en argument (si aucun prend les arguments courants)
92         sont des arguments valide pour une FORMULE.
93         Retourne :
94             - un booléen, qui vaut 1 si arguments licites, 0 sinon
95             - un message d'erreurs ('' si illicites)
96         """
97         if not arguments :
98             arguments = self.arguments
99         if not arguments :
100             return 0,"Une formule doit avoir au minimum un argument"
101         # il faut au préalable enlever les parenthèses ouvrantes et fermantes
102         # encadrant les arguments
103         arguments = string.strip(arguments)
104         if arguments[0] != '(':
105             return 0,tr("La liste des arguments d'une formule doit etre entre parentheses : parenthese ouvrante manquante")
106         if arguments[-1] != ')':
107             return 0,tr("La liste des arguments d'une formule doit etre entre parentheses : parenthese fermante manquante")
108         # on peut tester la syntaxe de chaque argument maintenant
109         erreur=''
110         test = 1
111         arguments = arguments[1:-1] # on enlève les parenthèses ouvrante et fermante
112         l_arguments = string.split(arguments,',')
113         return test,erreur
114
115     def verif_corps(self,corps=None,arguments=None):
116         """
117         Cette méthode a pour but de vérifier si le corps de la FORMULE
118         est syntaxiquement correct.
119         Retourne :
120             - un booléen, qui vaut 1 si corps de FORMULE licite, 0 sinon
121             - un message d'erreurs ('' si illicite)
122         """
123         if not corps :
124             corps = self.corps
125         if not arguments :
126             arguments = self.arguments
127         formule=(self.get_nom(),self.type_retourne,arguments,corps)
128         # on récupère la liste des constantes et des autres fonctions prédéfinies
129         # et qui peuvent être utilisées dans le corps de la formule courante
130         l_ctes,l_form = self.jdc.get_parametres_fonctions_avant_etape(self)
131         # on crée un objet vérificateur
132         try:
133             verificateur = self.interpreteur(formule=formule,
134                                              constantes = l_ctes,
135                                              fonctions = l_form)
136         except :
137             traceback.print_exc()
138             return 0,tr("Impossible de realiser la verification de la formule")
139         return verificateur.isvalid(),verificateur.report()
140
141     def verif_nom(self,nom=None):
142         """
143         Vérifie si le nom passé en argument (si aucun prend le nom courant)
144         est un nom valide pour une FORMULE.
145         Retourne :
146             - un booléen, qui vaut 1 si nom licite, 0 sinon
147             - un message d'erreurs ('' si illicite)
148         """
149         if not nom :
150             nom = self.get_nom()
151         if nom == "" :
152             return 0,tr("Pas de nom donne a la FORMULE")
153         if len(nom) > 8 :
154             return 0,tr("Un nom de FORMULE ne peut depasser 8 caracteres")
155         if nom[0] > "0" and nom[0] < "9" :
156             return 0,tr("Un nom de FORMULE ne peut pas commencer par un chiffre")
157         sd = self.parent.get_sd_autour_etape(nom,self)
158         if sd :
159             return 0,tr("Un concept de nom %s existe deja !" %nom)
160         return 1,''
161
162     def verif_type(self,type=None):
163         """
164         Vérifie si le type passé en argument (si aucun prend le type courant)
165         est un type valide pour une FORMULE.
166         Retourne :
167             - un booléen, qui vaut 1 si type licite, 0 sinon
168             - un message d'erreurs ('' si illicite)
169         """
170         if not type:
171             type = self.type_retourne
172         if not type :
173             return 0,tr("Le type de la valeur retournee n'est pas specifie")
174         if type not in self.l_types_autorises:
175             return 0,tr("Une formule ne peut retourner une valeur de type : %s" %type)
176         return 1,''
177
178     def verif_formule(self,formule=None):
179         """
180         Vérifie la validité de la formule passée en argument.
181         Cette nouvelle formule est passée sous la forme d'un tuple : (nom,type_retourne,arguments,corps)
182         Si aucune formule passée, prend les valeurs courantes de la formule
183         Retourne :
184             - un booléen, qui vaut 1 si formule licite, 0 sinon
185             - un message d'erreurs ('' si illicite)
186         """
187         if not formule :
188             formule = (None,None,None,None)
189         test_nom,erreur_nom = self.verif_nom(formule[0])
190         test_type,erreur_type = self.verif_type(formule[1])
191         if formule[2]:
192             args = '('+formule[2]+')'
193         else:
194             args = None
195         test_arguments,erreur_arguments = self.verif_arguments(args)
196         test_corps,erreur_corps = self.verif_corps(corps = formule[3], arguments = args)
197         # test global = produit des tests partiels
198         test = test_nom*test_type*test_arguments*test_corps
199         # message d'erreurs global = concaténation des messages partiels
200         erreur = ''
201         if not test :
202             for mess in (erreur_nom,erreur_type,erreur_arguments,erreur_corps):
203                 erreur = erreur+(len(mess) > 0)*'\n'+mess
204         return test,erreur
205
206     def verif_formule_python(self,formule=None):
207         """
208         Pour l instant ne fait qu un compile python
209         il serait possible d ajouter des tests sur les arguments
210         ou le type retourne mais ...
211         """
212         if not formule :
213             formule = (None,None,None,None)
214         test_nom,erreur_nom = self.verif_nom(formule[0])
215         if formule[2]:
216             args = '('+formule[2]+')'
217         else:
218             args = None
219         test_arguments,erreur_arguments = self.verif_arguments(args)
220         corps=formule[3]
221         erreur_formule= ''
222         test_formule=1
223         try :
224             compile(corps,'<string>','eval')
225         except :
226             erreur_formule= "le corps de la formule n'est pas une formule python valide"
227             test_formule=0
228         erreur = ''
229         test = test_nom*test_arguments*test_formule
230         if not test :
231             for mess in (erreur_nom,erreur_arguments,erreur_formule):
232                 erreur = erreur+(len(mess) > 0)*'\n'+mess
233         return test,erreur
234
235
236     def update(self,formule):
237         """
238         Méthode externe.
239         Met à jour les champs nom, type_retourne,arguments et corps de la FORMULE
240         par les nouvelles valeurs passées dans le tuple formule.
241         On stocke les valeurs SANS vérifications.
242         """
243         self.type_retourne = formule[1]
244         self.arguments = '('+formule[2]+')'
245         self.corps = formule[3]
246         # il faut ajouter le mot-clé simple correspondant dans mc_liste
247         # pour cela on utilise la méthode générale build_mc
248         # du coup on est obligé de modifier le dictionnaire valeur de self ...
249         self.valeur = {}
250         self.valeur[self.type_retourne] = self.arguments+' = ' + self.corps
251         self.McBuild()
252         sd = self.get_sd_prod()
253         if sd:
254             sd.nom = formule[0]
255
256     # bidouille PN 
257     # Il faut que formule soit constituee de 
258     # nom de la formule
259     # type retourne
260     # parametres
261     # corps de la fonction
262     # il faut aussi que les arguments soient sous forme de tuple
263     def update_formule_python(self,formule):
264         self.build_mc()
265         self.mc_liste=[]
266         if len(formule) < 4 :
267            return 0
268         arguments=formule[3]
269         if arguments[0] == '(' :
270            arguments=arguments[1:]
271         if arguments[-1] == ')' :
272            arguments=arguments[:-1]
273         self.arguments=tuple(arguments.split(','))
274
275         mocles={"NOM_PARA":self.arguments}
276         if formule[1] == "REEL":
277           mocles["VALE"]=formule[2]
278         if formule[1] == "COMPLEXE":
279           mocles["VALE_C"]=formule[2]
280
281         for k,v in self.definition.entites.items():
282             if not mocles.has_key(k):continue
283             child=self.definition.entites[k](None,nom=k,parent=self)
284             child.valeur=mocles[k]
285             child.state = 'modified'
286             self.mc_liste.append(child)
287            
288         self.corps = formule[2]
289         self.type_retourne = formule[1]
290         sd = self.get_sd_prod()
291         if sd:
292             sd.nom = formule[0]
293         self.init_modif()
294         return 1
295
296     def active(self):
297         """
298         Rend l'etape courante active.
299         Il faut ajouter la formule au contexte global du JDC
300         """
301         self.actif = 1
302         self.init_modif()
303         nom = self.get_nom()
304         if nom == '' : return
305         try:
306             self.jdc.append_fonction(self.sd)
307         except:
308             pass
309
310     def inactive(self):
311         """
312         Rend l'etape courante inactive
313         Il faut supprimer la formule du contexte global du JDC
314         """
315         self.actif = 0
316         self.init_modif()
317         if not self.sd : return
318         self.jdc.del_fonction(self.sd)
319
320     def update_concept(self,sd):
321         return
322
323     def delete_concept(self,sd):
324         """ 
325          Inputs :
326            - sd=concept detruit
327          Fonction :
328          Mettre a jour les mots cles de l etape et eventuellement le concept produit si reuse
329          suite à la disparition du concept sd
330          Seuls les mots cles simples MCSIMP font un traitement autre que de transmettre aux fils,
331          sauf les objets FORM_ETAPE qui doivent vérifier que le concept détruit n'est pas 
332          utilisé dans le corps de la fonction
333         """
334         self.init_modif()
335          
336     def replace_concept(self,old_sd,sd):
337         """
338          Inputs :
339            - old_sd=concept remplace
340            - sd = nouveau concept
341          Fonction :
342          Les objets FORM_ETAPE devraient vérifier que le concept remplacé n'est pas
343          utilisé dans le corps de la fonction
344         """
345         self.init_modif()
346