Salome HOME
commentaire
[tools/eficas.git] / Ihm / I_ETAPE.py
index b56652803c5f3a5c22cc90362272a91f590c26a7..7ece4b6f6d145eea0216487572b47b73d13bd19c 100644 (file)
@@ -1,37 +1,66 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2013   EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 """
 """
 # Modules Python
 """
 """
 # Modules Python
-import string,types
+from __future__ import absolute_import
+from __future__ import print_function
+import sys,re
+import types
 from copy import copy
 
 from copy import copy
 
+from Extensions.i18n import tr
+from Extensions.eficas_exception import EficasException
+
+# Objet re pour controler les identificateurs Python
+concept_re=re.compile(r'[a-zA-Z_]\w*$')
+
+# import rajoute suite a l'ajout de Build_sd --> a resorber
+import traceback
+import Noyau
+from Noyau import N_Exception
+from Noyau.N_Exception import AsException
+import Validation
+# fin import a resorber
+
 # Modules EFICAS
 # Modules EFICAS
-import I_MCCOMPO
+from . import I_MCCOMPO
+from . import CONNECTOR
+from Extensions import commande_comm
 
 class ETAPE(I_MCCOMPO.MCCOMPO):
 
 
 class ETAPE(I_MCCOMPO.MCCOMPO):
 
-   def __init__(self):
-      self.niveau=self.jdc
-
    def ident(self):
       return self.nom
 
    def ident(self):
       return self.nom
 
-   def get_fr(self):
-      """ 
-         Retourne l'attribut fr de self.definition 
-      """
-      try:
-         return self.definition.fr
-      except:
-         return ''
-
    def get_sdname(self):
    def get_sdname(self):
-      if CONTEXT.debug : print "SDNAME ",self.reuse,self.sd,self.sd.get_name()
+      #print "SDNAME ",self.reuse,self.sd,self.sd.get_name()
+      if CONTEXT.debug : 
+          print(("SDNAME ",  self.reuse,  self.sd,  self.sd.get_name()))
+      sdname=''
       if self.reuse != None:
         sdname= self.reuse.get_name()
       else:
       if self.reuse != None:
         sdname= self.reuse.get_name()
       else:
-        sdname=self.sd.get_name()
-      if string.find(sdname,'sansnom') != -1 or string.find(sdname,'SD_') != -1:
-        # dans le cas où la SD est 'sansnom' ou 'SD_' on retourne la chaîne vide
+        if self.sd:sdname=self.sd.get_name()
+      if sdname.find('sansnom') != -1 or sdname.find('SD_') != -1:
+        # dans le cas ou la SD est 'sansnom' ou 'SD_' on retourne la chaine vide
         return ''
       return sdname
 
         return ''
       return sdname
 
@@ -43,107 +72,147 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
 
    def init_modif(self):
       """
 
    def init_modif(self):
       """
-         Met l'état de l'étape à : modifié
+         Met l'etat de l'etape a : modifie
          Propage la modification au parent
          Propage la modification au parent
-         Si la fonction op_init existe, l'active
       """
       """
-      # Une action
-      # doit etre realisée apres init_modif et la validite reevaluée
-      # apres cette action. L'état modified de tous les objets doit etre
-      # preservé.
+      # init_modif doit etre appele avant de realiser une modification
+      # La validite devra etre recalculee apres cette modification
+      # mais dans l'appel a fin_modif pour preserver l'etat modified
+      # de tous les objets entre temps
+      #print "init_modif",self,self.parent
       self.state = 'modified'
       if self.parent:
         self.parent.init_modif()
 
    def fin_modif(self):
       """
       self.state = 'modified'
       if self.parent:
         self.parent.init_modif()
 
    def fin_modif(self):
       """
-          Méthode appelée une fois qu'une modification a été faite afin de 
-          déclencher d'éventuels traitements post-modification
+          Methode appelee une fois qu'une modification a ete faite afin de 
+          declencher d'eventuels traitements post-modification
           ex : INCLUDE et POURSUITE
           ex : INCLUDE et POURSUITE
+          Ne pas mettre de traitement qui risque d'induire des recursions (soit a peu pres rien)
       """
       """
-      if self.isvalid() :
-         if type(self.definition.op_init) == types.FunctionType :
-            # XXX Normalement en mode editeur g_context ne peut pas etre utilisé
-            apply(self.definition.op_init,(self,self.parent.g_context))   
-      self.state = 'modified'
-    
+      CONNECTOR.Emit(self,"valid")
+      if self.parent:
+        self.parent.fin_modif()
+
    def nomme_sd(self,nom) :
       """
    def nomme_sd(self,nom) :
       """
-          Cette méthode a pour fonction de donner un nom (nom) au concept 
-          produit par l'étape (self).
-          - si le concept n'existe pas, on essaye de le créer (à condition que l'étape soit valide ET non réentrante)
-          - si il existe déjà, on le renomme et on répercute les changements dans les autres étapes    
+          Cette methode a pour fonction de donner un nom (nom) au concept 
+          produit par l'etape (self).
+            - si le concept n'existe pas, on essaye de le creer a condition que l'etape soit valide ET non reentrante)
+            - si il existe dea, on le renomme et on repercute les changements dans les autres etapes    
           Les valeurs de retour sont :
           Les valeurs de retour sont :
-           0 si le nommage n'a pas pu etre mené à son terme,
-           1 dans le cas contraire
+            - 0 si le nommage n'a pas pu etre menea son terme,
+            - 1 dans le cas contraire
       """
       """
-      if len(nom) > 8 and self.jdc.definition.code == 'ASTER':
-        return 0,"Nom de concept trop long (maxi 8 caractères)"
+      # Le nom d'un concept doit etre un identificateur Python (toujours vrai ?)
+      if not concept_re.match(nom):
+         return 0, tr("Un nom de concept doit etre un identificateur Python")
+
+      #if len(nom) > 8 and self.jdc.definition.code == 'ASTER':
+      #  return 0, tr("Nom de concept trop long (maxi 8 caracteres)")
+
       self.init_modif()
       self.init_modif()
-      # Cas particulier des opérateurs réentrants
-      if not self.isvalid(sd='non') : return 0,"Nommage du concept refusé : l'opérateur n'est pas valide"
+      #
+      # On verifie d'abord si les mots cles sont valides
+      #
+      if not self.isvalid(sd='non') : return 0,"Nommage du concept refuse : l'operateur n'est pas valide"
+      #
+      # Cas particulier des operateurs obligatoirement reentrants
+      #
       if self.definition.reentrant == 'o':
       if self.definition.reentrant == 'o':
-        # FR : appel à get_sdprod incorrect : il faut appeler get_sd_avant_etape
-        #self.sd = self.reuse = self.jdc.get_sdprod(nom)
-       self.sd = self.reuse = self.jdc.get_sd_avant_etape(nom,self)
+        self.sd = self.reuse = self.jdc.get_sd_avant_etape(nom,self)
         if self.sd != None :
         if self.sd != None :
-          return 1,"Concept existant"
+          self.sdnom=self.sd.nom
+          self.fin_modif()
+          return 1, tr("Concept existant")
         else:
         else:
-          return 0,"Opérateur réentrant mais concept non existant"
+          return 0, tr("Operateur reentrant mais concept non existant")
+      #
+      # Cas particulier des operateurs facultativement reentrants
+      #
+      old_reuse=None
       if self.definition.reentrant == 'f' :
         sd = self.jdc.get_sd_avant_etape(nom,self)
         if sd != None :
       if self.definition.reentrant == 'f' :
         sd = self.jdc.get_sd_avant_etape(nom,self)
         if sd != None :
-         # FR : il faut tester que la sd trouvée est du bon type !!!!!!!!!!!!!!!!!
-         if isinstance(sd,self.get_type_produit()) :
+          if isinstance(sd,self.get_type_produit()) :
              self.sd = self.reuse = sd
              self.sd = self.reuse = sd
-             return 1,"Opérateur facultativement réentrant et concept existant trouvé"
-         else:
-            return 0,"Concept déjà existant et de mauvais type"
+             self.sdnom = sd.nom
+             self.fin_modif()
+             return 1, tr("Operateur reentrant et concept existant trouve")
+          else:
+             return 0, tr("Concept deja existant et de mauvais type")
         else :
         else :
-          # il faut éventuellement enlever le lien vers une SD existante car si on passe ici
-         # cela signifie que l'opérateur n'est pas utilisé en mode réentrant.
-         # Si on ne fait pas cela, le nom de l'opérateur réutilisé est aussi modifié
-         # et on ne peut plus modifier la SD de l'opérateur
-         if self.reuse :
-            self.sd = self.reuse = None
-      # l'opérateur n'est pas réentrant ou facultativement reentrant mais pas dans ce cas
+          # il faut enlever le lien vers une SD existante car si on passe ici
+          # cela signifie que l'operateur n'est pas utilise en mode reentrant.
+          # Si on ne fait pas cela, on risque de modifier une SD produite par un autre operateur
+          if self.reuse :
+             old_reuse=self.reuse
+             self.sd = self.reuse = self.sdnom = None
+      #
+      # On est dans le cas ou l'operateur n'est pas reentrant ou est facultativement reentrant
+      # mais est utilise en mode non reentrant
+      #
       if self.sd == None :
       if self.sd == None :
+          #Pas de concept produit preexistant
           if self.parent.get_sd_autour_etape(nom,self):
           if self.parent.get_sd_autour_etape(nom,self):
-            # On force self.valid a 0 car l appel a isvalid precedent l a mis a 1
-            # mais ceci indique seulement une validité partielle
-            # isvalid ne devrait peut etre pas mettre l attribut valid à 1 si sd == 'non'
-            self.valid=0
-            return 0,"Nommage du concept refuse : un concept de meme nom existe deja"
-          # Il n'existe pas de sd de nom sdnom. On peut donc créer le concept retourné.
-          # Il est créé sans nom mais enregistré dans la liste des concepts existants
-          self.get_sd_prod()
-          self.sd.nom = nom
-          return 1,"Nommage du concept effectué"
+            # Un concept de ce nom existe dans le voisinage de l'etape courante
+            # On retablit l'ancien concept reentrant s'il existait
+            if old_reuse:
+               self.sd=self.reuse=old_reuse
+               self.sdnom=old_reuse.nom
+            return 0, tr("Nommage du concept refuse : un concept de meme nom existe deja")
+          else:
+            # Il n'existe pas de concept de ce nom dans le voisinage de l'etape courante
+            # On peut donc creer le concept retourne
+            # Il est cree sans nom mais enregistre dans la liste des concepts existants
+            try:
+               self.get_sd_prod()
+               # Renommage du concept : Il suffit de changer son attribut nom pour le nommer
+               self.sd.nom = nom
+               self.sdnom=nom
+               self.parent.update_concept_after_etape(self,self.sd)
+               self.fin_modif()
+               return 1, tr("Nommage du concept effectue")
+            except:
+               return 0, tr("Nommage impossible %s", str(sys.exc_info()[1]))
       else :
       else :
-        old_nom=self.sd.nom
-        if string.find(old_nom,'sansnom') :
-           # Dans le cas où old_nom == sansnom, isvalid retourne 0 alors que ...
-          # par contre si le concept existe et qu'il s'appelle sansnom c'est que l'étape est valide
-          # on peut donc le nommer sans test préalable
-          self.sd.nom=nom
-           return 1,"Nommage du concept effectué"
-        if self.isvalid() :
-          # Normalement l appel de isvalid a mis a jour le concept produit (son type)
-          # Il suffit de spécifier l attribut nom de sd pour le nommer si le nom n est pas
-          # deja attribué
-          if self.parent.get_sd_autour_etape(nom,self):
-            return 0,"Nommage du concept refuse : un concept de meme nom existe deja"
+          #Un concept produit preexiste
+          old_nom=self.sd.nom
+          if old_nom.find('sansnom') :
+            # Dans le cas ou old_nom == sansnom, isvalid retourne 0 alors que ...
+            # par contre si le concept existe et qu'il s'appelle sansnom c'est que l'etape est valide
+            # on peut donc le nommer sans test prealable
+            if self.parent.get_sd_autour_etape(nom,self):
+              return 0, tr("Nommage du concept refuse : un concept de meme nom existe deja")
+            else:
+              # Renommage du concept : Il suffit de changer son attribut nom pour le nommer
+              self.sd.nom=nom
+              self.sdnom=nom
+              self.parent.update_concept_after_etape(self,self.sd)
+              self.fin_modif()
+              return 1, tr("Nommage du concept effectue")
+          if self.isvalid() :
+            # Normalement l appel de isvalid a mis a jour le concept produit (son type)
+            # Il suffit de specifier l attribut nom de sd pour le nommer si le nom n est pas
+            # deja attribue
+            if self.parent.get_sd_autour_etape(nom,self):
+              return 0, tr("Nommage du concept refuse : un concept de meme nom existe deja")
+            else:
+              # Renommage du concept : Il suffit de changer son attribut nom pour le nommer
+              self.sd.nom=nom
+              self.sdnom=nom
+              self.parent.update_concept_after_etape(self,self.sd)
+              self.fin_modif()
+              return 1, tr("Nommage du concept effectue")
           else:
           else:
-            self.sd.nom=nom
-            return 1,"Nommage du concept effectué"
-        else:
-          # Normalement on ne devrait pas passer ici
-          return 0,'Normalement on ne devrait pas passer ici'
+            # Normalement on ne devrait pas passer ici
+            return 0, 'Normalement on ne devrait pas passer ici'
 
    def get_sdprods(self,nom_sd):
       """ 
          Fonction : retourne le concept produit par l etape de nom nom_sd
 
    def get_sdprods(self,nom_sd):
       """ 
          Fonction : retourne le concept produit par l etape de nom nom_sd
-                    s il existe sinon None
+         s il existe sinon None
       """
       if self.sd:
         if self.sd.nom == nom_sd:return self.sd
       """
       if self.sd:
         if self.sd.nom == nom_sd:return self.sd
@@ -152,15 +221,18 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
       """
           Rend l'etape courante active.
           Il faut ajouter la sd si elle existe au contexte global du JDC
       """
           Rend l'etape courante active.
           Il faut ajouter la sd si elle existe au contexte global du JDC
-          et à la liste des sd
+          et a la liste des sd
       """
       """
+      if self.actif:return
       self.actif = 1
       self.actif = 1
-      if not self.sd : return
-      # XXX Pourquoi faut-il faire ce qui suit ??? par defaut les etapes sont actives
-      try:
-        self.jdc.append_sdprod(self.sd)
-      except:
-        pass
+      self.init_modif()
+      if self.sd :
+        try:
+          self.jdc.append_sdprod(self.sd)
+        except:
+          pass
+      CONNECTOR.Emit(self,"add",None)
+      CONNECTOR.Emit(self,"valid")
 
    def inactive(self):
       """
 
    def inactive(self):
       """
@@ -169,38 +241,83 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
           et de la liste des sd
       """
       self.actif = 0
           et de la liste des sd
       """
       self.actif = 0
-      if not self.sd : return
-      self.jdc.del_sdprod(self.sd)
-      self.jdc.delete_concept_after_etape(self,self.sd)
+      self.init_modif()
+      if self.sd :
+         self.jdc.del_sdprod(self.sd)
+         self.jdc.delete_concept_after_etape(self,self.sd)
+      CONNECTOR.Emit(self,"supp",None)
+      CONNECTOR.Emit(self,"valid")
+
+   def control_sdprods(self,d):
+      """
+          Cette methode doit verifier que ses concepts produits ne sont pas
+          deja definis dans le contexte
+          Si c'est le cas, les concepts produits doivent etre supprimes
+      """
+      #print "control_sdprods",d.keys(),self.sd and self.sd.nom,self.nom
+      if self.sd:
+        if self.sd.nom in d :
+           # Le concept est deja defini
+           if self.reuse and self.reuse is d[self.sd.nom]:
+              # Le concept est reutilise : situation normale
+              pass
+           else:
+              # Redefinition du concept, on l'annule
+              #XXX on pourrait simplement annuler son nom pour conserver les objets
+              # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
+              self.init_modif()
+              sd=self.sd
+              self.sd=self.reuse=self.sdnom=None
+              #supprime les references a sd dans les etapes suivantes
+              self.parent.delete_concept_after_etape(self,sd)
+              self.fin_modif()
+
+   def supprime_sdprod(self,sd):
+      """
+         Supprime le concept produit sd s'il est produit par l'etape
+      """
+      if sd is not self.sd:return
+      if self.sd != None :
+         self.init_modif()
+         self.parent.del_sdprod(sd)
+         self.sd=None
+         self.fin_modif()
+         self.parent.delete_concept(sd)
 
    def supprime_sdprods(self):
       """ 
 
    def supprime_sdprods(self):
       """ 
-          Fonction:
+            Fonction:
             Lors d'une destruction d'etape, detruit tous les concepts produits
             Lors d'une destruction d'etape, detruit tous les concepts produits
-            Un opérateur n a qu un concept produit 
+            Un operateur n a qu un concept produit 
             Une procedure n'en a aucun
             Une procedure n'en a aucun
-            Une macro en a en général plus d'un
+            Une macro en a en general plus d'un
       """
       """
-      # XXX pour les macros il faudrait peut etre aussi 
-      #     supprimer les concepts a droite du = ???
-      if not self.is_reentrant() :
-        # l'étape n'est pas réentrante
-        # le concept retourné par l'étape est à supprimer car il était 
-        # créé par l'étape
-        if self.sd != None :
-          self.parent.del_sdprod(self.sd)
-          self.parent.delete_concept(self.sd)
+      #print "supprime_sdprods",self
+      if self.reuse is self.sd :return
+      # l'etape n'est pas reentrante
+      # le concept retourne par l'etape est a supprimer car il etait 
+      # cree par l'etape
+      if self.sd != None :
+         self.parent.del_sdprod(self.sd)
+         self.parent.delete_concept(self.sd)
+
+   def close(self):
+      return
+
+   def update_concept(self,sd):
+      for child in self.mc_liste :
+          child.update_concept(sd)
 
    def delete_concept(self,sd):
       """ 
           Inputs :
 
    def delete_concept(self,sd):
       """ 
           Inputs :
-             sd=concept detruit
+             sd=concept detruit
           Fonction :
           Fonction :
-             Mettre a jour les mots cles de l etape et eventuellement 
-             le concept produit si reuse
-             suite à la disparition du concept sd
-             Seuls les mots cles simples MCSIMP font un traitement autre 
-             que de transmettre aux fils
+          Mettre a jour les mots cles de l etape et eventuellement 
+          le concept produit si reuse
+          suite a la disparition du concept sd
+          Seuls les mots cles simples MCSIMP font un traitement autre 
+          que de transmettre aux fils
       """
       if self.reuse and self.reuse == sd:
         self.sd=self.reuse=None
       """
       if self.reuse and self.reuse == sd:
         self.sd=self.reuse=None
@@ -208,50 +325,28 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
       for child in self.mc_liste :
         child.delete_concept(sd)
 
       for child in self.mc_liste :
         child.delete_concept(sd)
 
-   def make_register(self):
+   def replace_concept(self,old_sd,sd):
       """
       """
-         Initialise les attributs jdc, id, niveau et réalise les
-         enregistrements nécessaires
-         Pour EFICAS, on tient compte des niveaux
+          Inputs :
+             - old_sd=concept remplace
+             - sd = nouveau concept 
+          Fonction :
+          Mettre a jour les mots cles de l etape et eventuellement
+          le concept produit si reuse
+          suite au remplacement  du concept old_sd
       """
       """
-      if self.parent :
-         self.jdc = self.parent.get_jdc_root()
-         self.id=   self.parent.register(self)
-         if self.definition.niveau :
-            # La définition est dans un niveau. En plus on
-            # l'enregistre dans le niveau
-            self.nom_niveau_definition = self.definition.niveau.nom
-            self.niveau = self.parent.dict_niveaux[self.nom_niveau_definition]
-            self.niveau.register(self)
-         else:
-            # La définition est au niveau global
-            self.nom_niveau_definition = 'JDC'
-            self.niveau=self.parent
-      else:
-         self.jdc = self.parent =None
-         self.id=None
-         self.niveau=None
+      if self.reuse and self.reuse == old_sd:
+        self.sd=self.reuse=sd
+        self.init_modif()
+      for child in self.mc_liste :
+        child.replace_concept(old_sd,sd)
 
 
-   def copy(self):
-      """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
-          et sans sd 
-      """
-      etape = copy(self)
-      etape.sd = None
-      etape.state = 'modified'
-      etape.reuse = None
-      etape.sdnom = None
-      etape.etape=etape
-      etape.mc_liste=[]
-      for objet in self.mc_liste:
-        new_obj = objet.copy()
-        new_obj.reparent(etape)
-        etape.mc_liste.append(new_obj)
-      return etape
+   def reset_context(self):
+      pass
 
    def get_noms_sd_oper_reentrant(self):
       """ 
 
    def get_noms_sd_oper_reentrant(self):
       """ 
-          Retourne la liste des noms de concepts utilisés à l'intérieur de la commande
+          Retourne la liste des noms de concepts utilisesa l'interieur de la commande
           qui sont du type que peut retourner cette commande 
       """
       liste_sd = self.get_sd_utilisees()
           qui sont du type que peut retourner cette commande 
       """
       liste_sd = self.get_sd_utilisees()
@@ -259,7 +354,7 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
       if type(self.definition.sd_prod) == types.FunctionType:
         d=self.cree_dict_valeurs(self.mc_liste)
         try:
       if type(self.definition.sd_prod) == types.FunctionType:
         d=self.cree_dict_valeurs(self.mc_liste)
         try:
-          classe_sd_prod = apply(self.definition.sd_prod,(),d)
+          classe_sd_prod = self.definition.sd_prod(*(), **d)
         except:
           return []
       else:
         except:
           return []
       else:
@@ -269,109 +364,129 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
       l_noms.sort()
       return l_noms
 
       l_noms.sort()
       return l_noms
 
-   def get_sd_utilisees(self):
-      """ 
-          Retourne la liste des concepts qui sont utilisés à l'intérieur d'une commande
-          ( comme valorisation d'un MCS) 
-      """
-      l=[]
-      for child in self.mc_liste:
-        l.extend(child.get_sd_utilisees())
-      return l
+   def get_genealogie_precise(self):
+      return [self.nom]
 
    def get_genealogie(self):
       """ 
           Retourne la liste des noms des ascendants de l'objet self
 
    def get_genealogie(self):
       """ 
           Retourne la liste des noms des ascendants de l'objet self
-          en s'arretant à la première ETAPE rencontrée
+          en s'arretant a la premiere ETAPE rencontree
       """
       return [self.nom]
 
       """
       return [self.nom]
 
-   def reparent(self,parent):
-     """
-         Cette methode sert a reinitialiser la parente de l'objet
-     """
-     self.parent=parent
-     self.jdc=parent.get_jdc_root()
-     self.etape=self
-     for mocle in self.mc_liste:
-        mocle.reparent(self)
-
    def verif_existence_sd(self):
      """
    def verif_existence_sd(self):
      """
-        Vérifie que les structures de données utilisées dans self existent bien dans le contexte
-       avant étape, sinon enlève la référence à ces concepts
+        Verifie que les structures de donnees utilisees dans self existent bien dans le contexte
+        avant etape, sinon enleve la referea ces concepts
      """
      """
+     #print "verif_existence_sd",self.sd
      for motcle in self.mc_liste :
          motcle.verif_existence_sd()
      for motcle in self.mc_liste :
          motcle.verif_existence_sd()
+
+   def update_mc_global(self):
+     """
+        Met a jour les mots cles globaux enregistres dans l'etape
+        et dans le jdc parent.
+        Une etape ne peut pas etre globale. Elle se contente de passer
+        la requete a ses fils apres avoir reinitialise le dictionnaire 
+        des mots cles globaux.
+     """
+     self.mc_globaux={}
+     I_MCCOMPO.MCCOMPO.update_mc_global(self)
+
+   def update_condition_bloc(self):
+     """
+        Realise l'update des blocs conditionnels fils de self
+     """
+     self._update_condition_bloc()
+
+   def get_objet_commentarise(self,format):
+      """
+          Cette methode retourne un objet commande commentarisee
+          representant la commande self
+      """
+      import generator
+      g=generator.plugins[format]()
+      texte_commande = g.gener(self,format='beautifie')
+      # Il faut enlever la premiere ligne vide de texte_commande que
+      # rajoute le generator
+      # on construit l'objet COMMANDE_COMM repesentatif de self mais non
+      # enregistre dans le jdc (pas ajoute dans jdc.etapes)
+      parent=self.parent
+      pos=self.parent.etapes.index(self)
+      # on ajoute une fin à la commande pour pouvoir en commenter 2
+      texte_commande+='\nFin Commentaire'
+      commande_comment = commande_comm.COMMANDE_COMM(texte=texte_commande,
+                                                     reg='non',
+                                                     parent=parent)
+      self.parent.suppentite(self)
+      parent.addentite(commande_comment,pos)
+
+      return commande_comment
+
+   def modified(self):
+      """Le contenu de l'etape (mots cles, ...) a ete modifie"""
+      if self.nom=="DETRUIRE":
+        self.parent.control_context_apres(self)
+
+
      
      
+#ATTENTION SURCHARGE: a garder en synchro ou a reintegrer dans le Noyau
    def Build_sd(self,nom):
       """
    def Build_sd(self,nom):
       """
-         Construit le concept produit de l'opérateur. Deux cas 
-         peuvent se présenter :
-        
-         - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création 
-           et le nommage du concept.
+           Methode de Noyau surchargee pour poursuivre malgre tout
+           si une erreur se produit pendant la creation du concept produit
+      """
+      try:
+         sd=Noyau.N_ETAPE.ETAPE.Build_sd(self,nom)
+      except AsException as e :
+         # Une erreur s'est produite lors de la construction du concept
+         # Comme on est dans EFICAS, on essaie de poursuivre quand meme
+         # Si on poursuit, on a le choix entre deux possibilites :
+         # 1. on annule la sd associee a self
+         # 2. on la conserve mais il faut la retourner
+         # En plus il faut rendre coherents sdnom et sd.nom
+         self.sd=None
+         self.sdnom=None
+         self.state="unchanged"
+         self.valid=0
 
 
-         - le parent est défini. Dans ce cas, l'étape demande au parent la création et 
-           le nommage du concept.
+      return self.sd
 
 
+#ATTENTION SURCHARGE: cette methode doit etre gardee en synchronisation avec Noyau
+   def make_register(self):
       """
       """
-      if not self.isactif():return
-      # FR : attention cette méthode ne devrait pas se trouver là car elle surcharge celle qui 
-      # se trouve dans N_ETAPE.py et elle est partie intégrante du noyau, mais, suite à l'absence de 
-      # test de validité de l'opérateur avant d'essayer de déterminer la sd produite, on n'arrivait
-      # pas à relire avec EFICAS un fichier contenant une étape encore incomplète du style :
-      #  sansnom = AFFE_CHAR_CINE(MODELE=None)
-      # Suite à la stabilisation du noyau d'Aster, je n'ai pas eu d'autre solution que de surcharger
-      # cette méthode ici en rajoutant le test manquant ...
-      if not self.isvalid(sd='non') : return
-      try:
-         if self.parent:
-            sd= self.parent.create_sdprod(self,nom)
-            if type(self.definition.op_init) == types.FunctionType: 
-               apply(self.definition.op_init,(self,self.parent.g_context))
+         Initialise les attributs jdc, id, niveau et realise les
+         enregistrements necessaires
+         Pour EFICAS, on tient compte des niveaux
+         Surcharge la methode make_register du package Noyau
+      """
+      if self.parent :
+         self.jdc = self.parent.get_jdc_root()
+         self.id=   self.parent.register(self)
+         self.UserError=self.jdc.UserError
+         if self.definition.niveau :
+            # La definition est dans un niveau. En plus on
+            # l'enregistre dans le niveau
+            self.nom_niveau_definition = self.definition.niveau.nom
+            self.niveau = self.parent.dict_niveaux[self.nom_niveau_definition]
+            self.niveau.register(self)
          else:
          else:
-            sd=self.get_sd_prod()
-            # On n'utilise pas self.definition.op_init car self.parent 
-            # n'existe pas
-            if sd != None and self.reuse == None:
-               # On ne nomme le concept que dans le cas de non reutilisation 
-               # d un concept
-               sd.nom=nom
-         if self.jdc and self.jdc.par_lot == "NON" :
-            self.Execute()
-         return sd
-      except AsException,e:
-         raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
-                              'fichier : ',self.appel[1],e)
-      except EOFError:
-         # XXX Normalement le contexte courant doit etre le parent.
-         # Il n'y a pas de raison de remettre le contexte au parent
-         #self.reset_current_step()
-         raise
-      except :
-         l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
-         raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
-                           'fichier : ',self.appel[1]+'\n',
-                            string.join(l))
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-        
-     
+            # La definition est au niveau global
+            self.nom_niveau_definition = 'JDC'
+            self.niveau=self.parent
+      else:
+         self.jdc = self.parent =None
+         self.id=None
+         self.niveau=None
+         self.UserError="UserError"
+
+   def report(self):
+     cr= Validation.V_ETAPE.ETAPE.report(self)
+     #rafraichisst de la validite de l'etape (probleme avec l'ordre dans les macros : etape puis mots cles)
+     self.isvalid()
+     if not self.isvalid() and self.nom == "INCLUDE" :
+        self.cr.fatal(('Etape : %s ligne : %r  %s'),
+        self.nom, self.appel[0],  tr("\n   Include Invalide. \n  ne sera pas pris en compte"))
+     return cr
+