]> SALOME platform Git repositories - tools/eficas.git/blob - Ihm/I_MACRO_ETAPE.py
Salome HOME
CCAR: corrections diverses dans le cas d'insertion d'un include avec concepts de
[tools/eficas.git] / Ihm / I_MACRO_ETAPE.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 """
22 """
23 # Modules Python
24 import sys
25 import traceback,types,string
26
27 # Modules Eficas
28 import I_ETAPE
29 from Noyau.N_ASSD import ASSD
30
31 # import rajoutés suite à l'ajout de Build_sd --> à résorber
32 import Noyau, Validation.V_MACRO_ETAPE
33 from Noyau import N_Exception
34 from Noyau.N_Exception import AsException
35 import Accas # attention aux imports circulaires
36 # fin import à résorber
37
38 class MACRO_ETAPE(I_ETAPE.ETAPE):
39
40   def __init__(self):
41       self.typret=None
42       self.recorded_units={}
43
44   def get_sdprods(self,nom_sd):
45     """ 
46          Fonction : retourne le concept produit par l etape de nom nom_sd
47          s il existe sinon None
48     """
49     if self.sd and self.sd.nom == nom_sd :return self.sd
50     for co in self.sdprods:
51       if co.nom == nom_sd:return co
52     if type(self.definition.op_init) == types.FunctionType:
53       d={}
54       apply(self.definition.op_init,(self,d))
55       return d.get(nom_sd,None)
56     return None
57
58   def get_contexte_jdc(self,fichier,text):
59     """ 
60          Interprète text comme un texte de jdc et retourne le 
61          contexte final
62          cad le dictionnaire des sd disponibles à la dernière étape
63          Si text n'est pas un texte de jdc valide, retourne None
64          ou leve une exception
65          --> utilisée par ops.POURSUITE et INCLUDE
66     """
67     #print "get_contexte_jdc"
68     try:
69        # on essaie de créer un objet JDC auxiliaire avec un contexte initial
70        # Attention get_contexte_avant retourne un dictionnaire qui contient
71        # le contexte courant. Ce dictionnaire est reactualise regulierement.
72        # Si on veut garder l'etat du contexte fige, il faut en faire une copie.
73        context_ini = self.parent.get_contexte_avant(self).copy()
74
75        # Indispensable avant de creer un nouveau JDC
76        CONTEXT.unset_current_step()
77        args=self.jdc.args
78        prefix_include=None
79        if hasattr(self,'prefix'):
80           prefix_include=self.prefix
81        # ATTENTION : le dictionnaire recorded_units sert à memoriser les unites des 
82        # fichiers inclus. Il est preferable de garder le meme dictionnaire pendant
83        # tout le traitement et de ne pas le reinitialiser brutalement (utiliser 
84        # clear plutot) si on ne veut pas perdre la memoire des unites.
85        # En principe si la memorisation est faite au bon moment il n'est pas necessaire
86        # de prendre cette precaution mais ce n'est pas vrai partout.
87        old_recorded_units=self.recorded_units.copy()
88        #print "get_contexte_jdc",id(self.recorded_units)
89        #self.recorded_units.clear()
90
91        j=self.JdC_aux( procedure=text, nom=fichier,
92                                 appli=self.jdc.appli,
93                                 cata=self.jdc.cata,
94                                 cata_ord_dico=self.jdc.cata_ordonne_dico,
95                                 context_ini = context_ini,
96                                 jdc_pere=self.jdc,etape_include=self,
97                                 prefix_include=prefix_include,
98                                 recorded_units=self.recorded_units,
99                                 old_recorded_units=old_recorded_units,**args)
100
101        j.analyse()
102        # On récupère les étapes internes (pour validation)
103        self.etapes=j.etapes
104        self.jdc_aux=j
105        #print "get_contexte_jdc",id(self.etapes)
106     except:
107        traceback.print_exc()
108        # On force le contexte (etape courante) à self
109        CONTEXT.unset_current_step()
110        CONTEXT.set_current_step(self)
111        return None
112
113     if not j.cr.estvide():
114        # Erreurs dans l'INCLUDE. On garde la memoire du fichier 
115        # mais on n'insere pas les concepts
116        # On force le contexte (etape courante) à self
117        CONTEXT.unset_current_step()
118        CONTEXT.set_current_step(self)
119        raise Exception("Impossible de relire le fichier\n"+str(j.cr))
120
121     if not j.isvalid():
122        # L'INCLUDE n'est pas valide.
123        # on produit un rapport d'erreurs
124        # On force le contexte (etape courante) à self
125        cr=j.report()
126        CONTEXT.unset_current_step()
127        CONTEXT.set_current_step(self)
128        raise Exception("Le fichier include contient des erreurs\n"+str(cr))
129
130     # Si aucune erreur rencontrée
131     # On recupere le contexte de l'include verifie
132     #print "context_ini",j.context_ini
133     #print "g_context",j.g_context
134     try:
135        j_context=j.get_verif_contexte()
136     except:
137        CONTEXT.unset_current_step()
138        CONTEXT.set_current_step(self)
139        raise
140
141     #print "context_ini",j.context_ini
142
143     # On remplit le dictionnaire des concepts produits inclus
144     # en retirant les concepts présents dans le  contexte initial
145     # On ajoute egalement le concept produit dans le sds_dict du parent
146     # sans verification car on est sur (verification integrée) que 
147     # le nommage est possible
148     self.g_context.clear()
149     for k,v in j_context.items():
150        if not context_ini.has_key(k) or context_ini[k] != v:
151            self.g_context[k]=v
152            self.parent.sds_dict[k]=v
153
154
155     # On recupere le contexte courant
156     self.current_context=j.current_context
157     self.index_etape_courante=j.index_etape_courante
158     self.jdc_aux=j
159
160     # XXX j.supprime() ???
161     # On rétablit le contexte (etape courante) à self
162     CONTEXT.unset_current_step()
163     CONTEXT.set_current_step(self)
164     #print "context_ini",self.jdc_aux.context_ini
165
166     return j_context
167
168   def reevalue_sd_jdc(self):
169      """
170          Avec la liste des SD qui ont été supprimées, propage la 
171          disparition de ces SD dans toutes les étapes et descendants
172      """
173      #print "reevalue_sd_jdc"
174      l_sd_supp,l_sd_repl = self.diff_contextes()
175      for sd in l_sd_supp:
176         self.parent.delete_concept_after_etape(self,sd)
177      for old_sd,sd in l_sd_repl:
178         self.parent.replace_concept_after_etape(self,old_sd,sd)
179
180   def diff_contextes(self):
181      """ 
182          Réalise la différence entre les 2 contextes 
183          old_contexte_fichier_init et contexte_fichier_init
184          cad retourne la liste des sd qui ont disparu ou ne derivent pas 
185          de la meme classe et des sd qui ont ete remplacees
186      """
187      if not hasattr(self,'old_contexte_fichier_init'):return [],[]
188      l_sd_suppressed = []
189      l_sd_replaced = []
190      for old_key in self.old_contexte_fichier_init.keys():
191        if not self.contexte_fichier_init.has_key(old_key):
192          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
193            l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
194        else:
195          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
196             # Un concept de meme nom existe
197             old_class=self.old_contexte_fichier_init[old_key].__class__
198             if not isinstance(self.contexte_fichier_init[old_key],old_class):
199                # S'il n'est pas d'une classe derivee, on le supprime
200                l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
201             else:
202                l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
203      return l_sd_suppressed,l_sd_replaced
204       
205   def control_sdprods(self,d):
206       """
207           Cette methode doit updater le contexte fournit par
208           l'appelant en argument (d) en fonction de sa definition
209           tout en verifiant que ses concepts produits ne sont pas
210           deja definis dans le contexte
211       """
212       if hasattr(self,"fichier_unite"):
213          self.update_fichier_init(self.fichier_unite)
214          self.init_modif()
215
216       if type(self.definition.op_init) == types.FunctionType:
217         apply(self.definition.op_init,(self,d))
218       if self.sd:
219         if d.has_key(self.sd.nom):
220            # Le concept est deja defini
221            if self.reuse and self.reuse is d[self.sd.nom]:
222               # Le concept est reutilise : situation normale
223               pass
224            else:
225               # Redefinition du concept, on l'annule
226               #XXX on pourrait simplement annuler son nom pour conserver les objets
227               # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
228               self.sd=self.reuse=self.sdnom=None
229               self.init_modif()
230         else:
231            # Le concept n'est pas defini, on peut updater d
232            d[self.sd.nom]=self.sd
233       # On verifie les concepts a droite du signe =
234       for co in self.sdprods:
235         if d.has_key(co.nom) and co is not d[co.nom] :
236            self.delete_concept(co)
237         else:
238            d[co.nom]=co
239        
240   def supprime_sdprod(self,sd):
241       """
242          Supprime le concept produit sd s'il est produit par l'etape
243       """
244       if sd in self.sdprods:
245          self.init_modif()
246          self.parent.del_sdprod(sd)
247          self.sdprods.remove(sd)
248          self.fin_modif()
249          self.parent.delete_concept(sd)
250          return
251
252       if sd is not self.sd :return
253       if self.sd is not None :
254          self.init_modif()
255          self.parent.del_sdprod(sd)
256          self.sd=None
257          self.fin_modif()
258          self.parent.delete_concept(sd)
259
260   def supprime_sdprods(self):
261       """
262           Fonction: Lors de la destruction de la macro-etape, detruit tous les concepts produits
263           Un opérateur n a qu un concept produit
264           Une procedure n'en a aucun
265           Une macro en a en général plus d'un
266       """
267       #print "supprime_sdprods"
268       if self.reuse is not self.sd :
269          # l'étape n'est pas réentrante
270          # le concept retourné par l'étape est à supprimer car il était
271          # créé par l'étape
272          if self.sd != None :
273             self.parent.del_sdprod(self.sd)
274             self.parent.delete_concept(self.sd)
275       # On détruit les concepts à droite du signe =
276       for co in self.sdprods:
277          self.parent.del_sdprod(co)
278          self.parent.delete_concept(co)
279       # Si la macro a des etapes et des concepts inclus, on les detruit
280       for nom_sd,co in self.g_context.items():
281          if not isinstance(co,ASSD):continue
282          self.parent.del_sdprod(co)
283          self.parent.delete_concept(co)
284       # On met g_context à blanc
285       self.g_context={}
286
287   def close(self):
288       #print "MACRO_ETAPE.close",self
289       if hasattr(self,"jdc_aux") and self.jdc_aux:
290          # La macro a un jdc auxiliaire inclus. On demande sa fermeture
291          self.jdc_aux.close()
292
293   def delete_concept(self,sd):
294       """
295           Fonction : Mettre a jour les mots cles de l etape et eventuellement
296           le concept produit si reuse suite à la disparition du concept sd
297           Seuls les mots cles simples MCSIMP font un traitement autre
298           que de transmettre aux fils
299       """
300       #print "delete_concept",sd
301       I_ETAPE.ETAPE.delete_concept(self,sd)
302       for etape in self.etapes:
303          etape.delete_concept(sd)
304
305   def replace_concept(self,old_sd,sd):
306       """
307           Fonction : Mettre a jour les mots cles de l etape et le concept produit si reuse 
308           suite au remplacement  du concept old_sd par sd
309       """
310       #print "replace_concept",old_sd,sd
311       I_ETAPE.ETAPE.replace_concept(self,old_sd,sd)
312       for etape in self.etapes:
313          etape.replace_concept(old_sd,sd)
314          
315   def change_fichier_init(self,new_fic,text):
316     """
317        Tente de changer le fichier include. Le precedent include est conservé
318        dans old_xxx
319     """
320     if not hasattr(self,'fichier_ini'):
321        self.fichier_ini=None
322        self.fichier_text=None
323        self.fichier_err="Le fichier n'est pas defini"
324        self.contexte_fichier_init={}
325        self.recorded_units={}
326        self.jdc_aux=None
327        self.fichier_unite="PasDefini"
328        import Extensions.jdc_include
329        self.JdC_aux=Extensions.jdc_include.JdC_include
330
331     self.old_fic = self.fichier_ini
332     self.old_text = self.fichier_text
333     self.old_err = self.fichier_err
334     self.old_context=self.contexte_fichier_init
335     self.old_units=self.recorded_units
336     self.old_etapes=self.etapes
337     self.old_jdc_aux=self.jdc_aux
338
339     self.fichier_ini = new_fic
340     self.fichier_text=text
341
342     try:
343        self.make_contexte_include(new_fic,text)
344     except:
345        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
346        self.fichier_err=string.join(l)
347        raise
348
349     # L'evaluation de text dans un JDC auxiliaire s'est bien passé
350     # on peut poursuivre le traitement
351     self.init_modif()
352     self.state="undetermined"
353     self.fichier_err=None
354     # On enregistre la modification de fichier
355     self.record_unite()
356     # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
357     self.parent.reset_context()
358
359     # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression
360     self.old_contexte_fichier_init=self.old_context
361     self.reevalue_sd_jdc()
362
363     self.fin_modif()
364
365   def restore_fichier_init(self):
366     """
367        Restaure le fichier init enregistre dans old_xxx
368     """
369     self.fichier_ini=self.old_fic
370     self.fichier_text=self.old_text
371     self.fichier_err=self.old_err
372     self.contexte_fichier_init=self.old_context
373     self.recorded_units=self.old_units
374     self.etapes=self.old_etapes
375     self.jdc_aux=self.old_jdc_aux
376
377   def force_fichier_init(self):
378     """
379        Force le remplacement du fichier init meme si le remplacant est en erreur
380     """
381     # Reinitialisation complete du compte-rendu d'erreurs
382     self.jdc_aux.cr=self.jdc_aux.CR()
383     # On remplit le dictionnaire des concepts produits inclus
384     # en retirant les concepts présents dans le  contexte initial
385     # On ajoute egalement le concept produit dans le sds_dict du parent
386     # sans verification car on est sur (verification integrée) que
387     # le nommage est possible
388     j_context=self.jdc_aux.get_contexte_avant(None)
389     self.g_context.clear()
390     context_ini=self.jdc_aux.context_ini
391     for k,v in j_context.items():
392        if not context_ini.has_key(k) or context_ini[k] != v:
393            self.g_context[k]=v
394            self.parent.sds_dict[k]=v
395     # On recupere le contexte courant
396     self.current_context=self.jdc_aux.current_context
397     self.index_etape_courante=self.jdc_aux.index_etape_courante
398     self.contexte_fichier_init = j_context
399
400     # On enregistre la modification de fichier
401     self.init_modif()
402     self.state="undetermined"
403     self.record_unite()
404     # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
405     self.parent.reset_context()
406
407     # On remplace les anciens concepts par les nouveaux (y compris ajouts 
408     # et suppression) et on propage les modifications aux etapes precedentes et suivantes
409     # reevalue_sd_jdc construit la liste des differences entre les contextes contexte_fichier_init
410     # et old_contexte_fichier_init et effectue les destructions et remplacements de concept
411     # necessaires
412     self.old_contexte_fichier_init=self.old_context
413     self.reevalue_sd_jdc()
414     self.fin_modif()
415
416     self.jdc_aux.force_contexte(self.g_context)
417
418
419   def make_contexte_include(self,fichier,text):
420     """
421         Cette méthode sert à créer un contexte en interprétant un texte source
422         Python
423     """
424     #print "make_contexte_include"
425     # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
426     contexte = self.get_contexte_jdc(fichier,text)
427     if contexte == None :
428       raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
429     else:
430       # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
431       # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
432       # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
433       # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
434       # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
435       # g_context est utilisé pour avoir les concepts produits par la macro
436       # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
437       self.contexte_fichier_init = contexte
438
439   def reevalue_fichier_init_OBSOLETE(self):
440       """Recalcule les concepts produits par le fichier enregistre"""
441       #print "reevalue_fichier_init"
442       old_context=self.contexte_fichier_init
443       try:
444          self.make_contexte_include(self.fichier_ini ,self.fichier_text)
445       except:
446          l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
447          self.fichier_err = string.join(l)
448          self.g_context={}
449          self.etapes=[]
450          self.jdc_aux=None
451          self.old_contexte_fichier_init=old_context
452          self.contexte_fichier_init={}
453          self.reevalue_sd_jdc()
454          return
455
456       # L'evaluation s'est bien passee
457       self.fichier_err = None
458       self.old_contexte_fichier_init=old_context
459       self.reevalue_sd_jdc()
460       #print "reevalue_fichier_init",self.jdc_aux.context_ini
461
462   def update_fichier_init(self,unite):
463       """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur 
464          les noms des fichiers
465          Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
466       """
467       #print "update_fichier_init",unite
468       self.fichier_err=None
469       self.old_contexte_fichier_init=self.contexte_fichier_init
470       old_fichier_ini=self.fichier_ini
471
472       #print "update_fichier_init",self,self.parent,self.parent.recorded_units
473
474       #if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite):
475       if not self.parent.recorded_units.has_key(unite):
476          # Le numero d'unite a ete change. Le nouveau numero ne fait pas partie des numeros
477          # enregistres.
478          f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
479          if f is not None:
480             self.fichier_ini = f
481             self.fichier_text=text
482          #print "update_fichier_init",self.recorded_units
483       else:
484          # Unite existante
485          f,text,units=self.parent.recorded_units[unite]
486          self.fichier_ini = f
487          self.fichier_text=text
488          self.recorded_units=units
489
490       if self.fichier_ini is None:
491          # Le fichier n'est pas défini
492          self.fichier_err="Le fichier associé n'est pas défini"
493          self.parent.change_unit(unite,self,self.fichier_unite)
494          self.g_context={}
495          self.etapes=[]
496          self.jdc_aux=None
497          self.contexte_fichier_init={}
498          self.parent.reset_context()
499          self.reevalue_sd_jdc()
500          return
501
502       if old_fichier_ini == self.fichier_ini:
503          # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
504          #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
505          return
506
507       try:
508         self.make_contexte_include(self.fichier_ini,self.fichier_text)
509         # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
510         # avant d'appeler change_unit
511         self.parent.change_unit(unite,self,self.fichier_unite)
512       except:
513         # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
514         l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
515         # On conserve la memoire du nouveau fichier
516         # mais on n'utilise pas les concepts crees par ce fichier
517         # on met l'etape en erreur : fichier_err=string.join(l)
518         self.fichier_err=string.join(l)
519         self.parent.change_unit(unite,self,self.fichier_unite)
520         self.g_context={}
521         self.etapes=[]
522         self.jdc_aux=None
523         self.contexte_fichier_init={}
524
525       # Le contexte du parent doit etre reinitialise car les concepts 
526       # produits ont changé
527       self.parent.reset_context()
528       # Si des concepts ont disparu lors du changement de fichier, on 
529       # demande leur suppression
530       self.reevalue_sd_jdc()
531       #print "update_fichier_init",self.jdc_aux.context_ini
532
533   def record_unite(self):
534       if self.nom == "POURSUITE":
535          self.parent.record_unit(None,self)
536       else:
537          if hasattr(self,'fichier_unite') : 
538             self.parent.record_unit(self.fichier_unite,self)
539
540   def get_file_memo(self,unite=None,fic_origine=''):
541       """Retourne le nom du fichier et le source correspondant a l'unite unite
542          Initialise en plus recorded_units
543       """
544       #print "get_file_memo",unite,fic_origine,self,self.parent
545       #print self.parent.old_recorded_units
546       #print self.parent.recorded_units
547       if unite is None:
548          # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent
549          units={}
550       else:
551          # On est dans le cas d'un include. On reutilise toutes les unites de parent
552          units=self.parent.recorded_units
553
554       #if self.parent.old_recorded_units.has_key(unite):
555       if self.parent.recorded_units.has_key(unite):
556          f,text,units=self.parent.recorded_units[unite]
557          #f,text,units=self.parent.old_recorded_units[unite]
558          #print id(self.recorded_units)
559          self.recorded_units=units
560          #print id(self.recorded_units)
561          return f,text
562       elif self.jdc :
563          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
564       else:
565          f,text=None,None
566
567       self.recorded_units=units
568       if f is None and self.jdc.appli:
569          self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
570                           message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
571       return f,text
572
573 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
574   def get_file(self,unite=None,fic_origine=''):
575       """Retourne le nom du fichier et le source correspondant a l'unite unite
576       """
577       if self.jdc :
578          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
579       else:
580          f,text=None,None
581       return f,text
582
583 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
584   def make_include(self,unite=None):
585       """
586           Inclut un fichier dont l'unite logique est unite
587           Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
588           Si l'INCLUDE est invalide, la methode doit produire une exception 
589           Sinon on retourne None. Les concepts produits par l'INCLUDE sont
590           pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
591       """
592       #print "make_include",unite
593       # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
594       # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
595       del self.unite
596       # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
597       if not unite : return
598
599       if not hasattr(self,'fichier_ini') : 
600          # Si le fichier n'est pas defini on le demande
601          f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
602          # On memorise le fichier retourne
603          self.fichier_ini  = f
604          self.fichier_text = text
605          self.contexte_fichier_init={}
606          self.fichier_unite=unite
607          self.fichier_err=None
608          try:
609            import Extensions.jdc_include
610          except:
611            traceback.print_exc()
612            raise
613          self.JdC_aux=Extensions.jdc_include.JdC_include
614
615          if f is None:
616              self.fichier_err="Le fichier INCLUDE n est pas defini"
617              self.parent.record_unit(unite,self)
618              raise Exception(self.fichier_err)
619
620          try:
621            self.make_contexte_include(self.fichier_ini ,self.fichier_text)
622            self.parent.record_unit(unite,self)
623            #print "make_include.context_ini",self.jdc_aux.context_ini
624          except:
625            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
626            if self.jdc.appli:
627               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
628                                             message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
629                                            )
630            self.parent.record_unit(unite,self)
631            self.g_context={}
632            self.etapes=[]
633            self.jdc_aux=None
634            self.fichier_err = string.join(l)
635            self.contexte_fichier_init={}
636            raise
637
638       else:
639          # Si le fichier est deja defini on ne reevalue pas le fichier
640          # et on leve une exception si une erreur a été enregistrée
641          self.update_fichier_init(unite)
642          self.fichier_unite=unite
643          if self.fichier_err is not None: raise Exception(self.fichier_err)
644         
645
646 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
647   def make_contexte(self,fichier,text):
648     """
649         Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
650         en interprétant un texte source Python
651         Elle est appelee par la fonction sd_prd d'INCLUDE_MATERIAU
652     """
653     # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
654     # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
655     if hasattr(self,'mat'):del self.mat
656     self.fichier_ini =fichier
657     self.fichier_unite =fichier
658     self.fichier_text=text
659     self.fichier_err=None 
660     self.contexte_fichier_init={}
661     # On specifie la classe a utiliser pour le JDC auxiliaire
662     try:
663       import Extensions.jdc_include
664     except:
665       traceback.print_exc()
666       raise
667     self.JdC_aux=Extensions.jdc_include.JdC_include
668     try:
669        self.make_contexte_include(self.fichier_ini ,self.fichier_text)
670        self.parent.record_unit(self.fichier_unite,self)
671     except:
672        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
673        self.fichier_err = string.join(l)
674        self.parent.record_unit(self.fichier_unite,self)
675        self.g_context={}
676        self.etapes=[]
677        self.jdc_aux=None
678        self.contexte_fichier_init={}
679        raise
680
681 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
682   def update_sdprod(self,cr='non'):
683      # Cette methode peut etre appelee dans EFICAS avec des mots cles de 
684      # la commande modifies. Ceci peut conduire a la construction ou
685      # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
686      # Il faut donc positionner le current_step avant l'appel
687      CONTEXT.unset_current_step()
688      CONTEXT.set_current_step(self)
689      valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
690      CONTEXT.unset_current_step()
691      return valid
692
693 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro 
694   def Build_sd(self,nom):
695       """
696            Methode de Noyau surchargee pour poursuivre malgre tout
697            si une erreur se produit pendant la creation du concept produit
698       """
699       try:
700          sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
701       except AsException,e:
702          # Une erreur s'est produite lors de la construction du concept
703          # Comme on est dans EFICAS, on essaie de poursuivre quand meme
704          # Si on poursuit, on a le choix entre deux possibilités :
705          # 1. on annule la sd associée à self
706          # 2. on la conserve mais il faut la retourner
707          # On choisit de l'annuler
708          # En plus il faut rendre coherents sdnom et sd.nom
709          self.sd=None
710          self.sdnom=None
711          self.state="unchanged"
712          self.valid=0
713
714       return self.sd
715
716 #ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro 
717   def make_poursuite(self):
718       """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
719       """
720       #print "make_poursuite"
721       if not hasattr(self,'fichier_ini') :
722          # Si le fichier n'est pas defini on le demande
723          f,text=self.get_file_memo(fic_origine=self.parent.nom)
724          # On memorise le fichier retourne
725          self.fichier_ini = f
726          self.fichier_unite = None
727          self.fichier_text = text
728          self.fichier_err=None
729          try:
730            import Extensions.jdc_include
731          except:
732            traceback.print_exc()
733            raise
734          self.JdC_aux=Extensions.jdc_include.JdC_poursuite
735          self.contexte_fichier_init={}
736
737          if f is None:
738              self.fichier_err="Le fichier POURSUITE n'est pas defini"
739              self.parent.record_unit(None,self)
740              raise Exception(self.fichier_err)
741
742          try:
743            self.make_contexte_include(self.fichier_ini,self.fichier_text)
744            self.parent.record_unit(None,self)
745          except:
746            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
747            if self.jdc.appli:
748               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
749                                             message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
750                                            )
751            self.parent.record_unit(None,self)
752            self.g_context={}
753            self.etapes=[]
754            self.jdc_aux=None
755            self.fichier_err = string.join(l)
756            self.contexte_fichier_init={}
757            raise
758
759       else:
760          # Si le fichier est deja defini on ne reevalue pas le fichier
761          # et on leve une exception si une erreur a été enregistrée
762          self.update_fichier_init(None)
763          if self.fichier_err is not None: raise Exception(self.fichier_err)