Salome HOME
PN : Enleve Homard pour la v1.7
[tools/eficas.git] / Ihm / I_JDC.py
index 1765b2c534b791a20ee3cdc8480b25c5c9267931..f7ef14c0db99c29308f79a065213c027cb959240 100644 (file)
@@ -1,3 +1,23 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM 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
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
 """
 """
 # Modules Python
@@ -21,14 +41,8 @@ class JDC(I_OBJECT.OBJECT):
       self.params=[]
       self.fonctions=[]
       self._etape_context=None
-
-   def get_cmd(self,nomcmd):
-      """
-          Retourne l'objet de type COMMANDE de nom nomcmd
-      """
-      for cata in self.cata:
-         if hasattr(cata,nomcmd):
-            return getattr(cata,nomcmd)
+      self.recorded_units={}
+      self.old_recorded_units={}
 
    def get_sd_avant_du_bon_type(self,etape,types_permis):
       """
@@ -127,6 +141,9 @@ class JDC(I_OBJECT.OBJECT):
             objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
             objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
         self.etapes.insert(pos,objet)
+       # il faut vérifier que les concepts utilisés par objet existent bien
+       # à ce niveau d'arborescence
+       objet.verif_existence_sd()
         self.active_etapes()
         self.editmode=0
         self.reset_context()
@@ -147,6 +164,10 @@ class JDC(I_OBJECT.OBJECT):
           self.reset_context()
           self.active_etapes()
           return e
+        except AsException,e:
+          self.reset_current_step()
+          self.editmode=0
+          raise AsException("Impossible d ajouter la commande "+name + '\n' +str(e))
         except:
           traceback.print_exc()
           self.reset_current_step()
@@ -166,10 +187,40 @@ class JDC(I_OBJECT.OBJECT):
    def get_sd_avant_etape(self,nom_sd,etape):
       return self.get_contexte_avant(etape).get(nom_sd,None)
 
+   def get_sd_apres_etape_avec_detruire(self,nom_sd,sd,etape,avec='non'):
+      """ 
+           Cette méthode retourne la SD sd de nom nom_sd qui est éventuellement
+           définie apres etape en tenant compte des concepts detruits
+           Si avec vaut 'non' exclut etape de la recherche
+      """
+      ietap=self.etapes.index(etape)
+      if avec == 'non':ietap=ietap+1
+      d={nom_sd:sd}
+      for e in self.etapes[ietap:]:
+         if e.isactif():
+            e.update_context(d)
+            autre_sd=d.get(nom_sd,None)
+            if autre_sd is None:
+              # Le concept a ete detruit
+              return None
+            if autre_sd is not sd :
+              # L'etape produit un concept de meme nom
+              if hasattr(e,'reuse') and e.reuse == autre_sd:
+                 # Le concept etant reutilise, on interrompt la recherche. 
+                 # On considere qu'il n'y a pas de nouveau concept defini
+                 # meme si dans les etapes suivantes le concept est detruit
+                 # et un concept de meme nom créé.
+                 return None
+              else:
+                 # Le concept est produit par l'etape
+                 return autre_sd
+      # On n'a rien trouve. Pas de concept de nom nom_sd
+      return None
+
    def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
       """ 
            Cette méthode retourne la SD de nom nom_sd qui est éventuellement
-            définie apres etape 
+           définie apres etape 
            Si avec vaut 'non' exclut etape de la recherche
       """
       ietap=self.etapes.index(etape)
@@ -185,7 +236,7 @@ class JDC(I_OBJECT.OBJECT):
    def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
       """
            Fonction: retourne la SD de nom nom_sd qui est éventuellement
-            définie avant ou apres etape
+           définie avant ou apres etape
            Permet de vérifier si un concept de meme nom existe dans le périmètre 
            d'une étape
            Si avec vaut 'non' exclut etape de la recherche
@@ -194,6 +245,20 @@ class JDC(I_OBJECT.OBJECT):
       if sd:return sd
       return self.get_sd_apres_etape(nom_sd,etape,avec)
 
+   def get_contexte_apres(self,etape):
+      """
+         Retourne le dictionnaire des concepts connus apres etape
+         On tient compte des commandes qui modifient le contexte
+         comme DETRUIRE ou les macros
+         Si etape == None, on retourne le contexte en fin de JDC
+      """
+      if not etape: return self.get_contexte_avant(etape)
+
+      d=self.get_contexte_avant(etape)
+      if etape.isactif():etape.update_context(d)
+      self.index_etape_courante=self.index_etape_courante+1
+      return d
+
    def active_etapes(self):
       """
           Cette méthode a pour fonction de désactiver les étapes qui doivent
@@ -221,8 +286,14 @@ class JDC(I_OBJECT.OBJECT):
       """  
           Cette methode a pour fonction de supprimer une étape dans 
           un jeu de commandes
+          Retourne 1 si la suppression a pu être effectuée,
+          Retourne 0 dans le cas contraire
       """
       self.init_modif()
+      # On memorise le contexte avant l'etape a supprimer
+      d=self.get_contexte_avant(etape)
+      index_etape=self.etapes.index(etape)
+
       self.etapes.remove(etape)
       if etape.niveau is not self:
         # Dans ce cas l'étape est enregistrée dans un niveau
@@ -231,25 +302,14 @@ class JDC(I_OBJECT.OBJECT):
       etape.supprime_sdprods()
       self.active_etapes()
 
-   def del_sdprod(self,sd):
-      """
-          Supprime la SD sd de la liste des sd et des dictionnaires de contexte
-      """
-      if sd in self.sds : self.sds.remove(sd)
-      if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
-
-   def delete_concept(self,sd):
-      """ 
-          Inputs :
-             sd=concept detruit
-          Fonction :
-             Mettre a jour les etapes du JDC suite à la disparition du 
-             concept sd
-             Seuls les mots cles simples MCSIMP font un traitement autre 
-             que de transmettre aux fils
-      """
-      for etape in self.etapes :
-        etape.delete_concept(sd)
+      # Apres suppression de l'etape il faut controler que les etapes
+      # suivantes ne produisent pas des concepts DETRUITS dans op_init de etape
+      for e in self.etapes[index_etape:]:
+         e.control_sdprods(d)
+      
+      self.reset_context()
+      self.fin_modif()
+      return 1
 
    def analyse(self):
       self.compile()
@@ -257,28 +317,6 @@ class JDC(I_OBJECT.OBJECT):
       self.exec_compile()
       self.active_etapes()
 
-   def register(self,etape):
-      """ 
-           Cette méthode ajoute  etape dans la liste
-           des etapes self.etapes et retourne l identificateur d'étape
-           fourni par l appel a g_register
-           A quoi sert editmode ?
-           - Si editmode vaut 1, on est en mode edition de JDC. On cherche 
-           à enregistrer une étape que l'on a créée avec eficas (en passant 
-           par addentite) auquel cas on ne veut récupérer que son numéro 
-           d'enregistrement et c'est addentité qui l'enregistre dans 
-           self.etapes à la bonne place...
-           - Si editmode vaut 0, on est en mode relecture d'un fichier de 
-           commandes et on doit enregistrer l'étape à la fin de self.etapes 
-           (dans ce cas l'ordre des étapes est bien l'ordre chronologique 
-           de leur création   )
-      """
-      if not self.editmode:
-         self.etapes.append(etape)
-      else:
-         pass
-      return self.g_register(etape)
-
    def register_parametre(self,param):
       """
           Cette méthode sert à ajouter un paramètre dans la liste des paramètres
@@ -346,17 +384,6 @@ class JDC(I_OBJECT.OBJECT):
       if self.appli:
          self.appli.send_message(message)
 
-#XXX ne semble pas servir pour JDC
-#   def reevalue_sd_jdc(self):
-      #""" 
-          #Avec la liste des SD qui ont été supprimées, propage la disparition de ces
-          #SD dans toutes les étapes et descendants
-      #"""
-      #l_sd = self.diff_contextes()
-      #if len(l_sd) == 0 : return
-      #for sd in l_sd:
-        #self.jdc.delete_concept(sd)
-
    def init_modif(self):
       """
       Méthode appelée au moment où une modification va être faite afin de 
@@ -365,6 +392,7 @@ class JDC(I_OBJECT.OBJECT):
       self.state = 'modified'
 
    def fin_modif(self):
+      self.isvalid()
       pass
 
    def get_liste_mc_inconnus(self):
@@ -380,32 +408,6 @@ class JDC(I_OBJECT.OBJECT):
               if l : l_mc.extend(l)
      return l_mc    
 
-   def get_file(self,unite=None,fic_origine=''):
-      """
-          Retourne le nom du fichier correspondant à un numero d'unité
-          logique (entier) ainsi que le source contenu dans le fichier
-      """
-      if self.appli :
-         # Si le JDC est relié à une application maitre, on délègue la recherche
-         file,text = self.appli.get_file(unite,fic_origine)
-      else:
-         file = None
-         if unite != None:
-            if os.path.exists("fort."+str(unite)):
-               file= "fort."+str(unite)
-         if file == None :
-            raise AsException("Impossible de trouver le fichier correspondant \
-                               a l unite %s" % unite)
-         if not os.path.exists(file):
-            raise AsException("%s n'est pas un fichier existant" % unite)
-         fproc=open(file,'r')
-         text=fproc.read()
-         fproc.close()
-      text=string.replace(text,'\r\n','\n')
-      linecache.cache[file]=0,0,string.split(text,'\n'),file
-      return file,text
-
-
    def get_genealogie(self):
       """
           Retourne la liste des noms des ascendants de l'objet self
@@ -413,32 +415,6 @@ class JDC(I_OBJECT.OBJECT):
       """
       return []
 
-   def NommerSdprod(self,sd,sdnom):
-      """
-          Nomme la SD apres avoir verifie que le nommage est possible : nom
-          non utilise
-          Si le nom est deja utilise, leve une exception
-          Met le concept créé dans le concept global g_context
-      """
-      # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
-      # Le dictionnaire g_context ne représente pas le contexte
-      # effectif avant une étape.
-      # Il faut utiliser get_contexte_avant avec une indication de l'étape
-      # traitée. Pour le moment, il n'y a pas de moyen de le faire : ajouter 
-      # un attribut dans le JDC ???
-      if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
-      if self._etape_context:
-         o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
-      else:
-         o=self.g_context.get(sdnom,None)
-      if isinstance(o,ASSD):
-         raise AsException("Nom de concept deja defini : %s" % sdnom)
-
-      # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
-      # Ajoute a la creation (appel de reg_sd).
-      self.g_context[sdnom]=sd
-      sd.nom=sdnom
-
    def set_etape_context(self,etape):
       """
           Positionne l'etape qui sera utilisee dans NommerSdProd pour
@@ -455,6 +431,14 @@ class JDC(I_OBJECT.OBJECT):
       self.current_context={}
       self.index_etape_courante=0
 
+   def del_sdprod(self,sd):
+      """
+          Supprime la SD sd de la liste des sd et des dictionnaires de contexte
+      """
+      if sd in self.sds : self.sds.remove(sd)
+      if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
+      if self.sds_dict.has_key(sd.nom) : del self.sds_dict[sd.nom]
+
    def del_param(self,param):
       """
           Supprime le paramètre param de la liste des paramètres
@@ -471,3 +455,150 @@ class JDC(I_OBJECT.OBJECT):
       if fonction in self.fonctions : self.fonctions.remove(fonction)
       if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]
 
+   def append_sdprod(self,sd):
+      """
+          Ajoute la SD sd à la liste des sd en vérifiant au préalable qu'une SD de
+          même nom n'existe pas déjà
+      """
+      if sd == None or sd.nom == None:return
+
+      o=self.sds_dict.get(sd.nom,None)
+      if isinstance(o,ASSD):
+         raise AsException("Nom de concept deja defini : %s" % sd.nom)
+      self.sds_dict[sd.nom]=sd
+      self.g_context[sd.nom] = sd
+      if sd not in self.sds : self.sds.append(sd)
+
+   def append_param(self,param):
+      """
+          Ajoute le paramètre param à la liste des params
+          et au contexte global
+      """
+      # il faudrait vérifier qu'un paramètre de même nom n'existe pas déjà !!!
+      if param not in self.params : self.params.append(param)
+      self.g_context[param.nom]=param
+
+   def append_fonction(self,fonction):
+      """
+          Ajoute la fonction fonction à la liste des fonctions
+          et au contexte global
+      """
+      # il faudrait vérifier qu'une fonction de même nom n'existe pas déjà !!!
+      if fonction not in self.fonctions : self.fonctions.append(fonction)
+      self.g_context[fonction.nom]=fonction
+
+   def delete_concept(self,sd):
+      """
+          Inputs :
+             - sd=concept detruit
+          Fonction :
+          Mettre a jour les etapes du JDC suite à la disparition du
+          concept sd
+          Seuls les mots cles simples MCSIMP font un traitement autre
+          que de transmettre aux fils
+      """
+      for etape in self.etapes :
+        etape.delete_concept(sd)
+
+   def replace_concept_after_etape(self,etape,old_sd,sd):
+      """
+          Met à jour les étapes du JDC qui sont après etape en fonction
+          du remplacement du concept sd
+      """
+      index = self.etapes.index(etape)+1
+      if index == len(self.etapes) :
+         return # etape est la dernière étape du jdc ...on ne fait rien !
+      for child in self.etapes[index:]:
+        child.replace_concept(old_sd,sd)
+
+   def dump_state(self):
+      print "dump_state"
+      print "JDC.state: ",self.state
+      for etape in self.etapes :
+         print etape.nom+".state: ",etape.state
+      
+   def change_unit(self,unit,etape,old_unit):
+      if self.recorded_units.has_key(old_unit):del self.recorded_units[old_unit]
+      self.record_unit(unit,etape)
+
+   def record_unit(self,unit,etape):
+      """Enregistre les unites logiques incluses et les infos relatives a l'etape"""
+      if unit is None:
+         # Cas de POURSUITE
+         self.recorded_units[None]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
+      else:
+         self.recorded_units[unit]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+   def register(self,etape):
+      """
+           Cette méthode ajoute  etape dans la liste
+           des etapes self.etapes et retourne l identificateur d'étape
+           fourni par l appel a g_register
+
+           A quoi sert editmode ?
+              - Si editmode vaut 1, on est en mode edition de JDC. On cherche
+                à enregistrer une étape que l'on a créée avec eficas (en passant
+                par addentite) auquel cas on ne veut récupérer que son numéro
+                d'enregistrement et c'est addentité qui l'enregistre dans
+                self.etapes à la bonne place...
+              - Si editmode vaut 0, on est en mode relecture d'un fichier de
+                commandes et on doit enregistrer l'étape à la fin de self.etapes
+                (dans ce cas l'ordre des étapes est bien l'ordre chronologique
+                de leur création   )
+      """
+      if not self.editmode:
+         self.etapes.append(etape)
+      else:
+         pass
+      return self.g_register(etape)
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+   def NommerSdprod(self,sd,sdnom,restrict='non'):
+      """
+          Nomme la SD apres avoir verifie que le nommage est possible :
+          nom non utilise
+          Si le nom est deja utilise, leve une exception
+          Met le concept créé dans le concept global g_context
+      """
+      # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
+      # Le dictionnaire g_context ne représente pas le contexte
+      # effectif avant une étape.
+      # Il faut utiliser get_contexte_avant avec indication de l'étape
+      # traitée.
+      # Cette etape est indiquee par l'attribut _etape_context qui a ete
+      # positionné préalablement par un appel à set_etape_context
+
+      if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
+
+      if self._etape_context:
+         o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
+      else:
+         o=self.sds_dict.get(sdnom,None)
+
+      if isinstance(o,ASSD):
+         raise AsException("Nom de concept deja defini : %s" % sdnom)
+
+      # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
+      # Ajoute a la creation (appel de reg_sd).
+      self.sds_dict[sdnom]=sd
+      sd.nom=sdnom
+
+      # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC
+      if restrict == 'non':
+         self.g_context[sdnom]=sd
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+   def delete_concept_after_etape(self,etape,sd):
+      """
+          Met à jour les étapes du JDC qui sont après etape en fonction
+          de la disparition du concept sd
+      """
+      index = self.etapes.index(etape)+1
+      if index == len(self.etapes) :
+         return # etape est la dernière étape du jdc ...on ne fait rien !
+      for child in self.etapes[index:]:
+        child.delete_concept(sd)
+
+#ATTENTION SURCHARGE : les methodes ci-dessous surchargent des methodes de Noyau et Validation : a reintegrer
+