]> SALOME platform Git repositories - tools/eficas.git/blob - Ihm/I_JDC.py
Salome HOME
PN : correction de bug (suppression d un JDC vide)
[tools/eficas.git] / Ihm / I_JDC.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 types,traceback
25 import string,linecache
26
27 # Modules Eficas
28 import I_OBJECT
29 from Noyau.N_ASSD import ASSD
30 from Noyau.N_ETAPE import ETAPE
31 from Noyau.N_Exception import AsException
32 from Extensions import commentaire,parametre,parametre_eval
33 import CONNECTOR
34
35 class JDC(I_OBJECT.OBJECT):
36    """
37    """
38    def __init__(self):
39       self.editmode=0
40       self.etapes_niveaux=[]
41       self.niveau=self
42       self.params=[]
43       self.fonctions=[]
44       self._etape_context=None
45       self.recorded_units={}
46       self.old_recorded_units={}
47
48    def get_index(self,objet):
49       """
50         Retourne la position d'objet dans la liste self
51       """
52       return self.etapes.index(objet)
53
54    def get_sd_avant_du_bon_type(self,etape,types_permis):
55       """
56           Retourne la liste des concepts avant etape d'un type acceptable
57       """
58       d=self.get_contexte_avant(etape)
59       l=[]
60       for k,v in d.items():
61         if type(v) != types.InstanceType : continue
62         # On considère que seul assd indique un type quelconque pas CO
63         elif self.assd in types_permis :
64            l.append(k)
65         elif self.est_permis(v,types_permis):
66            l.append(k)
67       l.sort()
68       return l
69
70    def est_permis(self,v,types_permis):
71       for type_ok in types_permis:
72           if type_ok in ('R','I','C','TXM') and v in self.params : 
73              return 1
74           elif type_ok == 'R' and v.__class__.__name__ == 'reel' : 
75              return 1
76           elif type_ok == 'I' and v.__class__.__name__ == 'entier' : 
77              return 1
78           elif type_ok == 'C' and v.__class__.__name__ == 'complexe' : 
79              return 1
80           elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' : 
81              return 1
82           elif type(type_ok) != types.ClassType : 
83              continue
84           elif v.__class__ == type_ok or issubclass(v.__class__,type_ok):
85              return 1
86       return 0
87
88    def addentite(self,name,pos):
89       """
90           Ajoute une entite :
91           Si name est le nom d une commande ou un commentaire ajoute 
92           une etape au JDC
93           Sinon remonte une erreur
94       """
95       self.init_modif()
96       self.editmode=1
97       if name == "COMMENTAIRE" :
98         # ajout d'un commentaire
99         self.set_current_step()
100         ind = 1
101         for child in self.etapes :
102           if isinstance(child,commentaire.COMMENTAIRE):
103             ind = ind+1
104         objet = commentaire.COMMENTAIRE('',parent=self)
105         objet.nom = "_comm_"+`ind`
106         if pos == None : pos = 0
107         self.etapes.insert(pos,objet)
108         self.editmode=0
109         self.active_etapes()
110         CONNECTOR.Emit(self,"add",objet)
111         self.fin_modif()
112         return objet
113       elif name == "PARAMETRE":
114         # ajout d'un parametre
115         self.set_current_step()
116         nom_param = '_param_'+str(len(self.params)+1)
117         objet = parametre.PARAMETRE(nom=nom_param)
118         if pos == None : pos = 0
119         self.etapes.insert(pos,objet)
120         self.editmode=0
121         self.reset_context()
122         self.active_etapes()
123         CONNECTOR.Emit(self,"add",objet)
124         self.fin_modif()
125         return objet
126       elif name == "PARAMETRE_EVAL":
127         # ajout d'un parametre EVAL
128         self.set_current_step()
129         nom_param = '_param_'+str(len(self.params)+1)
130         objet = parametre_eval.PARAMETRE_EVAL(nom=nom_param)
131         if pos == None : pos = 0
132         self.etapes.insert(pos,objet)
133         self.editmode=0
134         self.reset_context()
135         self.active_etapes()
136         CONNECTOR.Emit(self,"add",objet)
137         self.fin_modif()
138         return objet
139       elif type(name)==types.InstanceType:
140         # on est dans le cas où on veut ajouter une commande déjà 
141         # existante (par copie donc)
142         # on est donc nécessairement en mode editeur ...
143         objet = name
144         # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
145         objet.reparent(self)
146         self.set_current_step()
147         if isinstance(objet,ETAPE):
148           if objet.nom_niveau_definition == 'JDC':
149             # l'objet dépend directement du JDC
150             objet.niveau = self
151           else:
152             # l'étape dépend d'un niveau et non directement du JDC :
153             # il faut l'enregistrer dans le niveau de parent
154             objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
155             objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
156         self.etapes.insert(pos,objet)
157         # il faut vérifier que les concepts utilisés par objet existent bien
158         # à ce niveau d'arborescence
159         objet.verif_existence_sd()
160         self.active_etapes()
161         self.editmode=0
162         self.reset_context()
163         CONNECTOR.Emit(self,"add",objet)
164         self.fin_modif()
165         return objet
166       else :
167         # On veut ajouter une nouvelle commande
168         try:
169           self.set_current_step()
170           cmd=self.get_cmd(name)
171           # L'appel a make_objet n'a pas pour effet d'enregistrer l'étape
172           # auprès du step courant car editmode vaut 1
173           # Par contre elle a le bon parent grace a set_current_step
174           e=cmd.make_objet()
175           if pos == None : pos = 0
176           self.etapes.insert(pos,e)
177           self.reset_current_step()
178           self.editmode=0
179           self.reset_context()
180           self.active_etapes()
181           CONNECTOR.Emit(self,"add",e)
182           self.fin_modif()
183           return e
184         except AsException,e:
185           self.reset_current_step()
186           self.editmode=0
187           raise AsException("Impossible d ajouter la commande "+name + '\n' +str(e))
188         except:
189           traceback.print_exc()
190           self.reset_current_step()
191           self.editmode=0
192           raise AsException("Impossible d ajouter la commande "+name)
193
194    def close(self):
195       #print "JDC.close",self
196       for etape in self.etapes:
197           if hasattr(etape,"close"):etape.close()
198       CONNECTOR.Emit(self,"close")
199
200    def set_current_step(self):
201       CONTEXT.unset_current_step()
202       CONTEXT.set_current_step(self)
203
204    def reset_current_step(self):
205       CONTEXT.unset_current_step()
206
207    def liste_mc_presents(self):
208       return []
209
210    def get_sd_avant_etape(self,nom_sd,etape):
211       return self.get_contexte_avant(etape).get(nom_sd,None)
212
213    def get_sd_apres_etape_avec_detruire(self,nom_sd,sd,etape,avec='non'):
214       """ 
215            Cette méthode retourne la SD sd de nom nom_sd qui est éventuellement
216            définie apres etape en tenant compte des concepts detruits
217            Si avec vaut 'non' exclut etape de la recherche
218       """
219       #print "JDC.get_sd_apres_etape_avec_detruire",nom_sd,sd
220       ietap=self.etapes.index(etape)
221       if avec == 'non':ietap=ietap+1
222       d={nom_sd:sd}
223       for e in self.etapes[ietap:]:
224          if e.isactif():
225             e.update_context(d)
226             autre_sd=d.get(nom_sd,None)
227             if autre_sd is None:
228               # Le concept a ete detruit. On interrompt la recherche car il n'y a
229               # pas eu de redefinition du concept (il n'y a pas de conflit potentiel).
230               return None
231             if autre_sd is not sd :
232               # L'etape produit un concept different de meme nom. La situation n'est
233               # pas saine (sauf peut etre si reuse ???)
234               if hasattr(e,'reuse') and e.reuse == autre_sd:
235                  # Le concept etant reutilise, on interrompt la recherche. 
236                  # On considere qu'il n'y a pas de nouveau concept defini
237                  # meme si dans les etapes suivantes le concept est detruit
238                  # et un concept de meme nom créé.
239                  # AVERIFIER : avec reuse le concept devrait etre le meme
240                  # le passage par ici est tres improbable
241                  return None
242               else:
243                  # Le concept est produit par l'etape (Il y a conflit potentiel).
244                  # Le concept est redefini par une etape posterieure.
245                  return autre_sd
246       # Pas de destruction du concept ni de redefinition. On retourne le
247       # concept initial
248       return sd
249
250    def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
251       """ 
252            Cette méthode retourne la SD de nom nom_sd qui est éventuellement
253            définie apres etape 
254            Si avec vaut 'non' exclut etape de la recherche
255       """
256       ietap=self.etapes.index(etape)
257       if avec == 'non':ietap=ietap+1
258       for e in self.etapes[ietap:]:
259         sd=e.get_sdprods(nom_sd)
260         if sd:
261           if hasattr(e,'reuse'):
262             if e.reuse != sd:
263               return sd
264       return None
265
266    def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
267       """
268            Fonction: retourne la SD de nom nom_sd qui est éventuellement
269            définie avant ou apres etape
270            Permet de vérifier si un concept de meme nom existe dans le périmètre 
271            d'une étape
272            Si avec vaut 'non' exclut etape de la recherche
273       """
274       sd=self.get_sd_avant_etape(nom_sd,etape)
275       if sd:return sd
276       return self.get_sd_apres_etape(nom_sd,etape,avec)
277
278    def get_contexte_apres(self,etape):
279       """
280          Retourne le dictionnaire des concepts connus apres etape
281          On tient compte des commandes qui modifient le contexte
282          comme DETRUIRE ou les macros
283          Si etape == None, on retourne le contexte en fin de JDC
284       """
285       if not etape: return self.get_contexte_avant(etape)
286
287       d=self.get_contexte_avant(etape)
288       if etape.isactif():etape.update_context(d)
289       self.index_etape_courante=self.index_etape_courante+1
290       return d
291
292    def active_etapes(self):
293       """
294           Cette méthode a pour fonction de désactiver les étapes qui doivent
295           l'être cad, dans le cas d'ASTER, les étapes qui ne sont pas 
296           comprises entre le premier DEBUT/POURSUITE et le premier FIN 
297           et rendre actives les autres
298       """
299       if self.definition.code == 'ASTER' :
300          # Seulement pour ASTER :
301          # Avant DEBUT actif vaut 0
302          # Apres DEBUT et avant le 1er FIN actif vaut 1
303          # Apres le 1er FIN actif vaut -1
304          actif=0
305       else:
306          actif=1
307       for etape in self.etapes:
308         if actif == 0 and etape.nom in ['DEBUT','POURSUITE']:actif=1
309         if actif == 1:
310            etape.active()
311         else:
312            etape.inactive()
313         if etape.nom == 'FIN':actif=-1
314
315    def suppentite(self,etape) :
316       """  
317           Cette methode a pour fonction de supprimer une étape dans 
318           un jeu de commandes
319           Retourne 1 si la suppression a pu être effectuée,
320           Retourne 0 dans le cas contraire
321       """
322       #print "suppentite",self
323       self.init_modif()
324       #PN correction de bugs 
325       if etape not in self.etapes:
326          return 0
327       index_etape=self.etapes.index(etape)
328       self.etapes.remove(etape)
329
330       if etape.niveau is not self:
331         # Dans ce cas l'étape est enregistrée dans un niveau
332         # Il faut la désenregistrer
333         etape.niveau.unregister(etape)
334
335       etape.supprime_sdprods()
336       etape.close()
337       self.active_etapes()
338
339       # Apres suppression de l'etape il faut controler que les etapes
340       # suivantes ne produisent pas des concepts DETRUITS dans op_init de etape
341       if index_etape > 0: 
342          index_etape=index_etape-1
343          etape=self.etapes[index_etape]
344       else:
345          etape=None
346       self.control_context_apres(etape)
347       
348       self.reset_context()
349       CONNECTOR.Emit(self,"supp",etape)
350       self.fin_modif()
351       return 1
352
353    def control_context_apres(self,etape):
354       """
355          Cette méthode verifie que les etapes apres l'etape etape
356          ont bien des concepts produits acceptables (pas de conflit de 
357          nom principalement)
358          Si des concepts produits ne sont pas acceptables ils sont supprimés.
359          Effectue les verifications sur les etapes du jdc mais aussi sur les
360          jdc parents s'ils existent.
361       """
362       #print "control_context_apres",self,etape
363       #Regularise les etapes du jdc apres l'etape etape
364       self.control_jdc_context_apres(etape)
365
366    def control_jdc_context_apres(self,etape):
367       """
368           Methode semblable a control_context_apres mais ne travaille
369           que sur les etapes et sous etapes du jdc
370       """
371       #print "control_jdc_context_apres",self,etape
372       if etape is None:
373          # on demarre de la premiere etape
374          index_etape=0
375       else:
376          index_etape=self.etapes.index(etape)+1
377
378       try:
379          etape=self.etapes[index_etape]
380       except:
381          #derniere etape du jdc : rien a faire
382          return
383
384       context=self.get_contexte_avant(etape)
385
386       for e in self.etapes[index_etape:]:
387           e.control_sdprods(context)
388           e.update_context(context)
389
390    def analyse(self):
391       self.compile()
392       if not self.cr.estvide():return
393       self.exec_compile()
394       self.active_etapes()
395
396    def register_parametre(self,param):
397       """
398           Cette méthode sert à ajouter un paramètre dans la liste des paramètres
399       """
400       self.params.append(param)
401
402    def register_fonction(self,fonction):
403       """
404           Cette méthode sert à ajouter une fonction dans la liste des fonctions
405       """
406       self.fonctions.append(fonction)
407
408    def delete_param(self,param):
409       """
410           Supprime le paramètre param de la liste des paramètres
411           et du contexte gobal
412       """
413       if param in self.params : self.params.remove(param)
414       if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
415
416    def get_parametres_fonctions_avant_etape(self,etape):
417       """
418           Retourne deux éléments :
419           - une liste contenant les noms des paramètres (constantes ou EVAL) 
420             définis avant etape
421           - une liste contenant les formules définies avant etape
422       """
423       l_constantes = []
424       l_fonctions = []
425       # on récupère le contexte avant etape
426       # on ne peut mettre dans les deux listes que des éléments de ce contexte
427       d=self.get_contexte_avant(etape)
428       # construction de l_constantes
429       for param in self.params:
430         nom = param.nom
431         if not nom : continue
432         if d.has_key(nom): l_constantes.append(nom)
433       # construction de l_fonctions
434       for form in self.fonctions:
435         nom = form.nom
436         if not nom : continue
437         if d.has_key(nom): l_fonctions.append(form.get_formule())
438
439       # on ajoute les concepts produits par DEFI_VALEUR
440       # XXX On pourrait peut etre faire plutot le test sur le type
441       # de concept : entier, reel, complexe, etc.
442       for k,v in d.items():
443          if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',):
444             l_constantes.append(k)
445
446       # on retourne les deux listes
447       return l_constantes,l_fonctions
448
449    def get_nb_etapes_avant(self,niveau):
450       """ 
451           Retourne le nombre d etapes avant le debut de niveau
452       """
453       nb=0
454       for niv in self.etapes_niveaux:
455         if niv == niveau:break
456         nb=nb+len(niv.etapes)
457       return nb
458
459    def send_message(self,message):
460       if self.appli:
461          self.appli.send_message(message)
462
463    def init_modif(self):
464       """
465       Méthode appelée au moment où une modification va être faite afin de 
466       déclencher d'éventuels traitements pré-modification
467       """
468       #print "init_modif",self
469       self.state = 'modified'
470
471    def fin_modif(self):
472       #print "fin_modif",self
473       CONNECTOR.Emit(self,"valid")
474       self.isvalid()
475       pass
476
477    def deep_update_condition_bloc(self):
478       # pour le moment, on ne fait rien
479       raise "Not implemented"
480
481    def update_condition_bloc(self):
482       # pour le moment, on ne fait rien
483       raise "Not implemented"
484
485    def get_liste_mc_inconnus(self):
486      """
487      Retourne une liste contenant les mots-clés inconnus à la relecture du JDC
488      """
489      # cette liste a le format suivant : [etape,(bloc,mcfact,...),nom_mc,valeur_mc]
490      l_mc = []
491      for etape in self.etapes :
492          if etape.isactif() :
493             if not etape.isvalid() :
494                l = etape.get_liste_mc_inconnus()
495                if l : l_mc.extend(l)
496      return l_mc    
497
498    def get_genealogie(self):
499       """
500           Retourne la liste des noms des ascendants de l'objet self
501           jusqu'à la première ETAPE parent.
502       """
503       return []
504
505    def get_liste_cmd(self):
506       """
507           Retourne la liste des commandes du catalogue
508       """
509       return self.niveau.definition.get_liste_cmd()
510
511    def get_groups(self):
512       """
513           Retourne la liste des groupes
514       """
515       return self.niveau.definition.liste_groupes,self.niveau.definition.dict_groupes
516
517    def set_etape_context(self,etape):
518       """
519           Positionne l'etape qui sera utilisee dans NommerSdProd pour
520           decider si le concept passé pourra etre  nommé
521       """
522       self._etape_context=etape
523
524    def reset_context(self):
525       """ 
526           Cette methode reinitialise le contexte glissant pour pouvoir
527           tenir compte des modifications de l'utilisateur : création
528           de commandes, nommage de concepts, etc.
529       """
530       #print "reset_context",self,self.nom
531       self.current_context={}
532       self.index_etape_courante=0
533    #   for etape in self.etapes:
534    #       etape.reset_context()
535
536    def del_sdprod(self,sd):
537       """
538           Supprime la SD sd de la liste des sd et des dictionnaires de contexte
539       """
540       #print "del_sdprod",self,sd
541       #print "del_sdprod",self.sds
542       #print "del_sdprod",self.g_context
543       #print "del_sdprod",self.sds_dict
544       if sd in self.sds : self.sds.remove(sd)
545       if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
546       if self.sds_dict.has_key(sd.nom) : del self.sds_dict[sd.nom]
547
548    def del_param(self,param):
549       """
550           Supprime le paramètre param de la liste des paramètres
551           et du contexte gobal
552       """
553       if param in self.params : self.params.remove(param)
554       if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
555
556    def del_fonction(self,fonction):
557       """
558           Supprime la fonction fonction de la liste des fonctions
559           et du contexte gobal
560       """
561       if fonction in self.fonctions : self.fonctions.remove(fonction)
562       if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]
563
564    def append_sdprod(self,sd):
565       """
566           Ajoute la SD sd à la liste des sd en vérifiant au préalable qu'une SD de
567           même nom n'existe pas déjà
568       """
569       if sd == None or sd.nom == None:return
570
571       o=self.sds_dict.get(sd.nom,None)
572       if isinstance(o,ASSD):
573          raise AsException("Nom de concept deja defini : %s" % sd.nom)
574       self.sds_dict[sd.nom]=sd
575       self.g_context[sd.nom] = sd
576       if sd not in self.sds : self.sds.append(sd)
577
578    def append_param(self,param):
579       """
580           Ajoute le paramètre param à la liste des params
581           et au contexte global
582       """
583       # il faudrait vérifier qu'un paramètre de même nom n'existe pas déjà !!!
584       if param not in self.params : self.params.append(param)
585       self.g_context[param.nom]=param
586
587    def append_fonction(self,fonction):
588       """
589           Ajoute la fonction fonction à la liste des fonctions
590           et au contexte global
591       """
592       # il faudrait vérifier qu'une fonction de même nom n'existe pas déjà !!!
593       if fonction not in self.fonctions : self.fonctions.append(fonction)
594       self.g_context[fonction.nom]=fonction
595
596    def delete_concept(self,sd):
597       """
598           Inputs :
599              - sd=concept detruit
600           Fonction :
601           Mettre a jour les etapes du JDC suite à la disparition du
602           concept sd
603           Seuls les mots cles simples MCSIMP font un traitement autre
604           que de transmettre aux fils
605       """
606       #print "delete_concept",self,sd
607       for etape in self.etapes :
608         etape.delete_concept(sd)
609
610    def replace_concept_after_etape(self,etape,old_sd,sd):
611       """
612           Met à jour les étapes du JDC qui sont après etape en fonction
613           du remplacement du concept sd
614       """
615       index = self.etapes.index(etape)+1
616       if index == len(self.etapes) :
617          return # etape est la dernière étape du jdc ...on ne fait rien !
618       for child in self.etapes[index:]:
619         child.replace_concept(old_sd,sd)
620
621    def update_concept_after_etape(self,etape,sd):
622       """
623           Met à jour les étapes du JDC qui sont après etape en fonction
624           de la modification (principalement nommage) du concept sd
625       """
626       if etape is None:
627          #On traite toutes les etapes
628          index=0
629       else:
630          index = self.etapes.index(etape)+1
631       if index == len(self.etapes) :
632          return # etape est la dernière étape du jdc ...on ne fait rien !
633       for child in self.etapes[index:]:
634         child.update_concept(sd)
635
636    def dump_state(self):
637       print "JDC.state: ",self.state
638       for etape in self.etapes :
639          print etape.nom+".state: ",etape.state
640       
641    def change_unit(self,unit,etape,old_unit):
642       #print "change_unit",unit,etape,old_unit
643       #print id(self.recorded_units),self.recorded_units
644       #if self.recorded_units.has_key(old_unit):del self.recorded_units[old_unit]
645       self.record_unit(unit,etape)
646
647    def record_unit(self,unit,etape):
648       """Enregistre les unites logiques incluses et les infos relatives a l'etape"""
649       #print "record_unit",unit,etape
650       if unit is None:
651          # Cas de POURSUITE
652          self.recorded_units[None]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
653       else:
654          self.recorded_units[unit]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
655       #print id(self.recorded_units),self.recorded_units
656       #print self.recorded_units.get(None,(None,"",{}))[2]
657       #print self.recorded_units.get(None,(None,"",{}))[2].get(None,(None,"",{}))
658
659    def changefichier(self,fichier):
660        self.fin_modif()
661
662 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
663    def register(self,etape):
664       """
665            Cette méthode ajoute  etape dans la liste
666            des etapes self.etapes et retourne l identificateur d'étape
667            fourni par l appel a g_register
668
669            A quoi sert editmode ?
670               - Si editmode vaut 1, on est en mode edition de JDC. On cherche
671                 à enregistrer une étape que l'on a créée avec eficas (en passant
672                 par addentite) auquel cas on ne veut récupérer que son numéro
673                 d'enregistrement et c'est addentité qui l'enregistre dans
674                 self.etapes à la bonne place...
675               - Si editmode vaut 0, on est en mode relecture d'un fichier de
676                 commandes et on doit enregistrer l'étape à la fin de self.etapes
677                 (dans ce cas l'ordre des étapes est bien l'ordre chronologique
678                 de leur création   )
679       """
680       if not self.editmode:
681          self.etapes.append(etape)
682       else:
683          pass
684       return self.g_register(etape)
685
686 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
687    def NommerSdprod(self,sd,sdnom,restrict='non'):
688       """
689           Nomme la SD apres avoir verifie que le nommage est possible :
690           nom non utilise
691           Si le nom est deja utilise, leve une exception
692           Met le concept créé dans le concept global g_context
693       """
694       # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
695       # Le dictionnaire g_context ne représente pas le contexte
696       # effectif avant une étape.
697       # Il faut utiliser get_contexte_avant avec indication de l'étape
698       # traitée.
699       # Cette etape est indiquee par l'attribut _etape_context qui a ete
700       # positionné préalablement par un appel à set_etape_context
701
702       if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
703
704       if self._etape_context:
705          o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
706       else:
707          o=self.sds_dict.get(sdnom,None)
708
709       if isinstance(o,ASSD):
710          raise AsException("Nom de concept deja defini : %s" % sdnom)
711
712       # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
713       # Ajoute a la creation (appel de reg_sd).
714       self.sds_dict[sdnom]=sd
715       sd.nom=sdnom
716
717       # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC
718       if restrict == 'non':
719          self.g_context[sdnom]=sd
720
721 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
722    def delete_concept_after_etape(self,etape,sd):
723       """
724           Met à jour les étapes du JDC qui sont après etape en fonction
725           de la disparition du concept sd
726       """
727       index = self.etapes.index(etape)+1
728       if index == len(self.etapes) :
729          return # etape est la dernière étape du jdc ...on ne fait rien !
730       for child in self.etapes[index:]:
731         child.delete_concept(sd)
732
733 #ATTENTION SURCHARGE : les methodes ci-dessous surchargent des methodes de Noyau et Validation : a reintegrer
734
735    def get_file(self,unite=None,fic_origine=''):
736       """
737           Retourne le nom du fichier correspondant à un numero d'unité
738           logique (entier) ainsi que le source contenu dans le fichier
739       """
740       if self.appli :
741          # Si le JDC est relié à une application maitre, on délègue la recherche
742          file,text= self.appli.get_file(unite,fic_origine)
743       else:
744          file = None
745          if unite != None:
746             if os.path.exists("fort."+str(unite)):
747                file= "fort."+str(unite)
748          if file == None :
749             raise AsException("Impossible de trouver le fichier correspondant"
750                                " a l unite %s" % unite)
751          if not os.path.exists(file):
752             raise AsException("%s n'est pas un fichier existant" % unite)
753          fproc=open(file,'r')
754          text=fproc.read()
755          fproc.close()
756       #if file == None : return None,None
757       text=string.replace(text,'\r\n','\n')
758       if file:
759          linecache.cache[file]=0,0,string.split(text,'\n'),file
760       return file,text
761