Salome HOME
Merge V9 dans Master
[tools/eficas.git] / Extensions / parametre.py
index bb244fe6337001b242617b104bcde9807109589d..38e0f2f65c10902d8e4ff545617eab2e27f5ace6 100644 (file)
 # -*- 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.
+# Copyright (C) 2007-2017   EDF R&D
 #
-# 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.
+# 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.
 #
-# 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.
+# 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
 #
-# ======================================================================
 """
-    Ce module contient la classe PARAMETRE qui sert à définir
-    des objets paramètres qui sont compréhensibles et donc affichables
+    Ce module contient la classe PARAMETRE qui sert a definir
+    des objets parametres qui sont comprehensibles et donc affichables
     par EFICAS.
-    Ces objets sont créés à partir de la modification du fichier de commandes
+    Ces objets sont crees a partir de la modification du fichier de commandes
     de l'utilisateur par le parseur de fichiers Python
 """
 
 # import de modules Python
-import string,types
+from __future__ import absolute_import
+from __future__ import print_function
+try :
+   from builtins import str
+   from builtins import range
+   from builtins import object
+except : pass
+
+import types
 from math import *
+import traceback
 
 # import de modules Eficas
 from Noyau.N_CR import CR
 from Noyau import N_OBJECT
 from Ihm import I_OBJECT
+from .param2 import *
+from Ihm import CONNECTOR
+from Extensions.i18n import tr
+from six.moves import range
 
-class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT) :
+class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
   """
-     Cette classe permet de créer des objets de type PARAMETRE
+     Cette classe permet de creer des objets de type PARAMETRE
      cad des affectations directes dans le jeu de commandes (ex: a=10.)
-     qui sont interprétées par le parseur de fichiers Python.
-     Les objets ainsi créés constituent des paramètres pour le jdc
+     qui sont interpretees par le parseur de fichiers Python.
+     Les objets ainsi crees constituent des parametres pour le jdc
   """
 
   nature = 'PARAMETRE'
   idracine = 'param'
 
   def __init__(self,nom,valeur=None):
-    # parent ne peut être qu'un objet de type JDC
-    self.dict_valeur=[]
-    self.valeur = self.interprete_valeur(valeur)
-    self.val=valeur
     self.nom = nom
-    # La classe PARAMETRE n'a pas de définition : on utilise self pour
-    # complétude
+    # La classe PARAMETRE n'a pas de definition : on utilise self pour
+    # completude
     self.definition=self
-    self.jdc = self.parent = CONTEXT.get_current_step()
+    # parent ne peut etre qu'un objet de type JDC
+    self.jdc = self.parent = CONTEXT.getCurrentStep()
     self.niveau=self.parent.niveau
     self.actif=1
     self.state='undetermined'
     self.register()
+    self.dict_valeur=[]
+    #self.valeur = self.interpreteValeur(valeur)
+    #self.val=valeur
+    self.valeur = valeur
+    self.val=repr(valeur)
 
-  def __getitem__(self,key):
-    param_item=ITEM_PARAMETRE(self,key)
-    return param_item
-
-  def __neg__(self):
-    try:
-      return -1*self.valeur
-    except:
-      print "******* Probleme : pas de valeur négative"
-      return None
-    
-  def __add__(self,a):
-    try :
-      return self.valeur+a.valeur
-    except :
-      print "******* Probleme : a l addition"
-      return None
-
-  def __radd__(self,a):
-    try :
-      return self.valeur+a.valeur
-    except :
-      print "******* Probleme : a l addition"
-      return None
-
-  def __sub__(self,a):
-    try :
-      return self.valeur  - a.valeur
-    except :
-      print "******* Probleme : a la soustraction"
-      return None
-
-  def __rsub__(self,a):
-    try :
-      return a.valeur - self.valeur
-    except :
-      print "******* Probleme : a la soustraction"
-      return None
-
-  def __mul__(self,a):
-    try :
-      return self.valeur*a.valeur
-    except :
-      print "******* Probleme : a la multiplication"
-      return None
-
-  def __rmul__(self,a):
-    try :
-      return self.valeur*a.valeur
-    except :
-      print "******* Probleme : a la multiplication"
-      return None
-
-  def __mul__(self,a):
-    try :
-      return self.valeur*a.valeur
-    except :
-      print "******* Probleme : a la multiplication"
-      return None
-
-  def __rmul__(self,a):
-    try :
-      return self.valeur*a.valeur
-    except :
-      print "******* Probleme : a la multiplication"
-      return None
-
-  def __add__(self,other):
-    try :
-      return self.valeur+other
-    except :
-      print "******* Probleme : a l addition"
-      return None
-
-  def __radd__(self,other):
-    try :
-      return self.valeur+other
-    except :
-      print "******* Probleme : a l addition"
-      return None
-
-  def __sub__(self,other):
-    try :
-      return self.valeur  - other
-    except :
-      print "******* Probleme : a la soustraction"
-      return None
-
-  def __rsub__(self,other):
-    try :
-      return other - self.valeur
-    except :
-      print "******* Probleme : a la soustraction"
-      return None
-
-  def  __mul__ (self,other):
-    retour=None
-    try :
-      retour = eval(self.valeur) * other
-    except :
-      try :
-         retour = self.valeur * other
-      except :
-         print "******* Probleme : a la multiplication"
-    return retour
-
-  def __rmul__ (self,other):
-    retour=None
-    try :
-      retour = eval(self.valeur) * other
-    except :
-      try :
-         retour = self.valeur * other
-      except :
-         print "******* Probleme : a la multiplication"
-    return retour
-
-
-  def __div__(self,other):
-    retour=None
-    try:
-      retour = eval(self.valeur) / other
-    except :
-      try :
-       retour = self.valeur / other
-      except :
-       print "******* Probleme : a la division"
-    return retour
-
-
-  def interprete_valeur(self,val):
+  def interpreteValeur(self,val):
     """
-    Essaie d'interpréter val (chaîne de caractères)comme :
+    Essaie d'interpreter val (chaine de caracteres)comme :
     - un entier
-    - un réel
-    - une chaîne de caractères
-    - une liste d'items d'un type qui précède
-    Retourne la valeur interprétée
+    - un reel
+    - une chaine de caracteres
+    - une liste d'items d'un type qui precede
+    Retourne la valeur interpretee
     """
-    if not val : return None
+    #if not val : return None
     valeur = None
-    #  on vérifie si val est un entier
-    try :
-        valeur = string.atoi(val)       # on a un entier
-        return valeur
-    except :
-        pass
-    #  on vérifie si val est un réel
-    try:
-        valeur = string.atof(val)   # on a un réel
-        return valeur
-    except :
-        pass
-    # on vérifie si val est un tuple
-    try :
-        valeur = eval(val)
-    except:
-        pass
+
+    if type(val) == list:
+    # Un premier traitement a ete fait lors de la saisie
+    # permet de tester les parametres qui sont des listes
+       l_new_val = []
+       for v in val :
+           try :
+               valeur=eval(str(v))
+               l_new_val.append(v)
+           except :
+               return None
+       return l_new_val
+
+    if type(val) == bytes:
+       # on tente l'evaluation dans un contexte fourni par le parent s'il existe
+       if self.parent:
+          valeur=self.parent.evalInContext(val,self)
+       else:
+          try :
+              valeur = eval(val)
+          except:
+              #traceback.print_exc()
+              pass
     #PN je n ose pas modifier je rajoute
+    # refus des listes heterogenes : ne dvrait pas etre la
     if valeur != None :
-        if type(valeur) == types.TupleType:
+        if type(valeur) == tuple:
             l_new_val = []
             typ = None
             for v in valeur :
@@ -229,27 +120,24 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT) :
                     typ = type(v)
                 else:
                     if type(v) != typ :
-                        # la liste est hétérogène --> on refuse d'interpréter
+                        # la liste est heterogene --> on refuse d'interpreter
                         #  self comme une liste
                         # on retourne la string initiale
-                        print 'liste hétérogène ',val
+                        print(('liste heterogene ',val))
                         return val
                 l_new_val.append(v)
             return tuple(l_new_val)
-       # PN : commente le print
-        #else:
-            # on a réussi à évaluer val en autre chose qu'un tuple ...
-            #print "on a réussi à évaluer %s en autre chose qu'un tuple ..." %val
-            #print 'on trouve : ',str(valeur),' de type : ',type(valeur)
-    # on retourne val comme une string car on n'a pas su l'interpréter
+
     if valeur != None :
        if type(valeur).__name__ == 'list':
           self.dict_valeur=[]
           for i in range(len(valeur)):
-             self.dict_valeur.append(valeur[i])
+             self.dict_valeur.append(valeur[i])
+       return valeur
+    # on retourne val comme une string car on n'a pas su l'interpreter
     return val
 
-  def get_valeurs(self):
+  def getValeurs(self):
     valeurretour=[]
     if self.dict_valeur != []:
        for val in self.dict_valeur:
@@ -258,121 +146,137 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT) :
         valeurretour.append(self.valeur)
     return valeurretour
 
-  def set_valeur(self,new_valeur):
+  def setValeur(self,new_valeur):
     """
-    Remplace la valeur de self par new_valeur interprétée
+    Remplace la valeur de self par new_valeur interpretee
     """
-    self.valeur = self.interprete_valeur(new_valeur)
-    self.init_modif()
+    self.valeur = self.interpreteValeur(new_valeur)
+    self.val=repr(self.valeur)
+    self.parent.updateConceptAfterEtape(self,self)
+    self.initModif()
 
-  def init_modif(self):
+  def setNom(self,new_nom):
     """
-    Méthode qui déclare l'objet courant comme modifié et propage
-    cet état modifié à ses ascendants
+    Change le nom du parametre
+    """
+    self.initModif()
+    self.nom=new_nom
+    self.finModif()
+
+  def initModif(self):
+    """
+    Methode qui declare l'objet courant comme modifie et propage
+    cet etat modifie a ses ascendants
     """
     self.state = 'modified'
     if self.parent:
-      self.parent.init_modif()
+      self.parent.initModif()
 
-  def get_jdc_root(self):
+  def getJdcRoot(self):
     if self.parent:
-      return self.parent.get_jdc_root()
+      return self.parent.getJdcRoot()
     else:
       return self
 
   def register(self):
     """
-    Enregistre le paramètre dans la liste des étapes de son parent (JDC)
+    Enregistre le parametre dans la liste des etapes de son parent (JDC)
     """
-    self.parent.register_parametre(self)
+    self.parent.registerParametre(self)
     self.parent.register(self)
 
-  def isvalid(self,cr='non'):
+  def isValid(self,cr='non'):
     """
     Retourne 1 si self est valide, 0 sinon
-    Un paramètre est considéré comme valide si :
+    Un parametre est considere comme valide si :
       - il a un nom
       - il a une valeur
     """
     if self.nom == '' :
         if cr == 'oui':
-           self.cr.fatal("Pas de nom donné au paramètre ")
+           self.cr.fatal(tr("Pas de nom donne au parametre "))
         return 0
     else:
         if self.valeur == None :
             if cr == 'oui' : 
-               self.cr.fatal("Le paramètre %s ne peut valoir None" % self.nom)
+               self.cr.fatal(tr("Le parametre %s ne peut valoir None" , self.nom))
             return 0
     return 1
 
-  def isoblig(self):
+  def isOblig(self):
     """
     Indique si self est obligatoire ou non : retourne toujours 0
     """
     return 0
 
-  def isrepetable(self):
+  def isRepetable(self):
     """
-    Indique si self est répétable ou non : retourne toujours 1
+    Indique si self est repetable ou non : retourne toujours 1
     """
     return 1
 
-  def liste_mc_presents(self):
+  def listeMcPresents(self):
     return []
 
   def supprime(self):
     """
-    Méthode qui supprime toutes les boucles de références afin que 
-    l'objet puisse être correctement détruit par le garbage collector
+    Methode qui supprime toutes les boucles de references afin que 
+    l'objet puisse etre correctement detruit par le garbage collector
     """
     self.parent = None
     self.jdc = None
     self.definition=None
+    self.niveau=None
 
   def active(self):
     """
     Rend l'etape courante active.
-    Il faut ajouter le paramètre au contexte global du JDC
+    Il faut ajouter le parametre au contexte global du JDC
     """
     self.actif = 1
     try:
-        self.jdc.append_param(self)
+        self.jdc.appendParam(self)
     except:
         pass
+    CONNECTOR.Emit(self,"add",None)
+    CONNECTOR.Emit(self,"valid")
 
   def inactive(self):
     """
     Rend l'etape courante inactive
-    Il faut supprimer le paramètre du contexte global du JDC
+    Il faut supprimer le parametre du contexte global du JDC
     """
     self.actif = 0
-    self.jdc.del_param(self)
-    self.jdc.delete_concept_after_etape(self,self)
+    self.jdc.delParam(self)
+    self.jdc.deleteConceptAfterEtape(self,self)
+    CONNECTOR.Emit(self,"supp",None)
+    CONNECTOR.Emit(self,"valid")
 
-  def isactif(self):
+  def isActif(self):
     """
-    Booléenne qui retourne 1 si self est actif, 0 sinon
+    Booleenne qui retourne 1 si self est actif, 0 sinon
     """
     return self.actif
 
-  def set_attribut(self,nom_attr,new_valeur):
+  def setAttribut(self,nom_attr,new_valeur):
     """
     Remplace la valeur de self.nom_attr par new_valeur)
     """
     if hasattr(self,nom_attr):
       setattr(self,nom_attr,new_valeur)
-      self.init_modif()
+      self.initModif()
 
-  def supprime_sdprods(self):
+  def supprimeSdProds(self):
     """
-    Il faut supprimer le paramètre qui a été entré dans la liste des
-    paramètres du JDC
+    Il faut supprimer le parametre qui a ete entre dans la liste des
+    parametres du JDC
     """
-    self.jdc.delete_param(self)
+    self.jdc.deleteParam(self)
+    self.parent.deleteConcept(self)
 
-  def update_context(self,d):
+  def updateContext(self,d):
     """
-    Update le dictionnaire d avec le paramètre que produit self
+    Update le dictionnaire d avec le parametre que produit self
     """
     d[self.nom]=self
 
@@ -380,69 +284,107 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT) :
     """
         Donne un echo de self sous la forme nom = valeur
     """
-    return self.nom+' = '+str(self.valeur)
+    if type(self.valeur) == bytes:
+         if self.valeur.find('\n') == -1:
+            # pas de retour chariot, on utilise repr
+            return self.nom+' = '+ repr(self.valeur)
+         elif self.valeur.find('"""') == -1:
+            # retour chariot mais pas de triple ", on formatte
+            return self.nom+' = """'+self.valeur+'"""'
+         else:
+            return self.nom+' = '+ repr(self.valeur)
+    else:
+       if type(self.valeur) == list :
+          aRetourner=self.nom+' = ['
+          for l in self.valeur :
+            aRetourner=aRetourner+str(l) +","
+          aRetourner=aRetourner[0:-1]+']'
+          return aRetourner
+       return self.nom+' = '+ str(self.valeur)
 
   def __str__(self):
     """
-        Retourne le nom du paramètre comme représentation de self
+        Retourne le nom du parametre comme representation de self
     """
     return self.nom
 
-  def get_sdprods(self,nom_sd):
+  def getSdprods(self,nom_sd):
      """
          Retourne les concepts produits par la commande
      """
      return None
 
   def report(self):
-    """ Génère l'objet rapport (classe CR) """
+    """ Genere l'objet rapport (classe CR) """
     self.cr=CR()
-    self.isvalid(cr='oui')
+    self.isValid(cr='oui')
     return self.cr
 
   def ident(self):
     """
-    Retourne le nom interne associé à self
+    Retourne le nom interne associe a self
     Ce nom n'est jamais vu par l'utilisateur dans EFICAS
     """
     return self.nom
 
-  def delete_concept(self,sd):
+  def deleteConcept(self,sd):
     pass
 
-  def replace_concept(self,old_sd,sd):
+  def replaceConcept(self,old_sd,sd):
     pass
 
-  def verif_condition_bloc(self):
+  def verifConditionBloc(self):
     """
         Evalue les conditions de tous les blocs fils possibles
-        (en fonction du catalogue donc de la définition) de self et
+        (en fonction du catalogue donc de la definition) de self et
         retourne deux listes :
-          - la première contient les noms des blocs à rajouter
-          - la seconde contient les noms des blocs à supprimer
+          - la premiere contient les noms des blocs a rajouter
+          - la seconde contient les noms des blocs a supprimer
     """
     return [],[]
 
-  def verif_condition_regles(self,liste_presents):
+  def verifConditionRegles(self,liste_presents):
     """
-        Retourne la liste des mots-clés à rajouter pour satisfaire les règles
-        en fonction de la liste des mots-clés présents
+        Retourne la liste des mots-cles a rajouter pour satisfaire les regles
+        en fonction de la liste des mots-cles presents
     """
     return []
 
-  def verif_existence_sd(self):
+  def verifExistenceSd(self):
      pass
 
-  def control_sdprods(self,d):
+  def controlSdprods(self,d):
       """sans objet """
       pass
 
   def close(self):
       pass
 
+  def resetContext(self):
+      pass
+
+  def eval(self):
+      if isinstance(self.valeur,Formula):
+         return self.valeur.eval()
+      else:
+         return self.valeur
+
+  def __adapt__(self,validator):
+      return validator.adapt(self.eval())
+
+class COMBI_PARAMETRE(object) :
+  def __init__(self,chainevaleur,valeur):
+      self.chainevaleur=chainevaleur
+      self.valeur=valeur
+
+  def __repr__(self):
+      return self.chainevaleur
 
+  def isValid(self):
+      if self.valeur and self.chainevaleur:
+         return 1
 
-class ITEM_PARAMETRE :
+class ITEM_PARAMETRE(object) :
   def __init__(self,param_pere,item=None):
       self.param_pere = param_pere
       self.item = item
@@ -452,14 +394,14 @@ class ITEM_PARAMETRE :
     return self.param_pere.nom+'['+str(self.item)+']'
 
 
-  def isvalid(self):
-      isvalid = 1
+  def isValid(self):
+      isValid = 1
       if self.item < 0:
-         isvalid =  0
+         isValid =  0
       try:
-        longueur= len(self.param_pere.dict_valeur) - 1
+         longueur= len(self.param_pere.dict_valeur) - 1
       except:
          longueur=0
       if self.item > longueur :
-         isvalid= 0
-      return isvalid
+         isValid= 0
+      return isValid