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