Salome HOME
pb python3
[tools/eficas.git] / Ihm / I_MCSIMP.py
index c3d8f4e0d27c8581b6ddd22a6dbf0bbd3e8b97c5..53067a77173f406a321d8bd92691654f7278be9f 100644 (file)
@@ -1,41 +1,46 @@
 # -*- coding: utf-8 -*-
 # -*- 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-2013   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
 #
 #
-# ======================================================================
-import types,string
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+from __future__ import absolute_import
+import types
 import traceback
 from copy import copy
 import traceback
 from copy import copy
-from repr import Repr
+from six.moves.reprlib import Repr
+from Extensions.i18n import tr
+from Extensions.eficas_exception import EficasException
+from six.moves import range
 myrepr = Repr()
 myrepr.maxstring = 100
 myrepr.maxother = 100
 
 from Noyau.N_utils import repr_float
 myrepr = Repr()
 myrepr.maxstring = 100
 myrepr.maxother = 100
 
 from Noyau.N_utils import repr_float
+import Validation
+from . import CONNECTOR
 
 
-# Attention : les classes ASSD,.... peuvent etre surchargées
-# dans le package Accas. Il faut donc prendre des précautions si
+# Attention : les classes ASSD,.... peuvent etre surchargees
+# dans le package Accas. Il faut donc prendre des precautions si
 # on utilise les classes du Noyau pour faire des tests (isxxxx, ...)
 # on utilise les classes du Noyau pour faire des tests (isxxxx, ...)
-# Si on veut créer des objets comme des CO avec les classes du noyau
+# Si on veut creer des objets comme des CO avec les classes du noyau
 # ils n'auront pas les conportements des autres packages (pb!!!)
 # ils n'auront pas les conportements des autres packages (pb!!!)
-# Il vaut mieux les importer d'Accas mais problème d'import circulaire,
-# on ne peut pas les importer au début.
-# On fait donc un import local quand c'est nécessaire (peut occasionner
+# Il vaut mieux les importer d'Accas mais probleme d'import circulaire,
+# on ne peut pas les importer au debut.
+# On fait donc un import local quand c'est necessaire (peut occasionner
 # des pbs de prformance).
 from Noyau.N_ASSD import ASSD,assd
 from Noyau.N_GEOM import GEOM,geom
 # des pbs de prformance).
 from Noyau.N_ASSD import ASSD,assd
 from Noyau.N_GEOM import GEOM,geom
@@ -44,11 +49,25 @@ import Accas
 # fin attention
 
 from Extensions import parametre
 # fin attention
 
 from Extensions import parametre
-import I_OBJECT
-import CONNECTOR
+from Extensions import param2
+from . import I_OBJECT
+from . import CONNECTOR
+from .I_VALIDATOR import ValError,listProto
 
 class MCSIMP(I_OBJECT.OBJECT):
 
 
 class MCSIMP(I_OBJECT.OBJECT):
 
+
+  def isvalid(self,cr='non'):
+      if self.state == 'unchanged':
+        return self.valid
+      for type_permis in self.definition.type:
+          if hasattr(type_permis, "__class__") and type_permis.__class__.__name__ == 'Matrice':
+             self.monType=type_permis
+             return self.valideMatrice(cr=cr)
+      if self.definition.siValide != None :
+            self.definition.siValide(self)
+      return Validation.V_MCSIMP.MCSIMP.isvalid(self,cr=cr)
+
   def GetNomConcept(self):
       p=self
       while p.parent :
   def GetNomConcept(self):
       p=self
       while p.parent :
@@ -66,56 +85,57 @@ class MCSIMP(I_OBJECT.OBJECT):
 
   def GetText(self):
     """
 
   def GetText(self):
     """
-        Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
-        pointé par self
+        Retourne le texte a afficher dans l'arbre representant la valeur de l'objet
+        pointe par self
     """
 
     if self.valeur == None : 
       return None
     """
 
     if self.valeur == None : 
       return None
-    elif type(self.valeur) == types.FloatType : 
-      # Traitement d'un flottant isolé
-      # txt = repr_float(self.valeur)
-      # Normalement str fait un travail correct
+    elif type(self.valeur) == float : 
+      # Traitement d'un flottant isole
       txt = str(self.valeur)
       clefobj=self.GetNomConcept()
       txt = str(self.valeur)
       clefobj=self.GetNomConcept()
-      if self.jdc.appli.dict_reels.has_key(clefobj):
-        if self.jdc.appli.dict_reels[clefobj].has_key(self.valeur):
-           txt=self.jdc.appli.dict_reels[clefobj][self.valeur]
-    elif type(self.valeur) in (types.ListType,types.TupleType) :
+      if clefobj in self.jdc.appli.appliEficas.dict_reels :
+        if self.valeur in self.jdc.appli.appliEficas.dict_reels[clefobj]:
+           txt=self.jdc.appli.appliEficas.dict_reels[clefobj][self.valeur]
+    elif type(self.valeur) in (list,tuple) :
+      if self.valeur==[] or self.valeur == (): return str(self.valeur)
       # Traitement des listes
       txt='('
       # Traitement des listes
       txt='('
-      i=0
+      sep=''
       for val in self.valeur:
       for val in self.valeur:
-        if type(val) == types.FloatType : 
-           # CCAR : Normalement str fait un travail correct
-           #txt=txt + i*',' + repr_float(val)
+        if type(val) == float : 
            clefobj=self.GetNomConcept()
            clefobj=self.GetNomConcept()
-           if self.jdc.appli.dict_reels.has_key(clefobj):
-              if self.jdc.appli.dict_reels[clefobj].has_key(val):
-                 txt=txt + i*',' +self.jdc.appli.dict_reels[clefobj][val]
+           if clefobj in self.jdc.appli.appliEficas.dict_reels:
+              if val in self.jdc.appli.appliEficas.dict_reels[clefobj]:
+                 txt=txt + sep +self.jdc.appli.appliEficas.dict_reels[clefobj][val]
               else :
               else :
-                 txt=txt + i*',' + str(val)
+                 txt=txt + sep + str(val)
            else :
            else :
-              txt=txt + i*',' + str(val)
-        elif isinstance(val,ASSD): 
-           txt = txt + i*',' + val.get_name()
-    #PN
-    # ajout du elif
-        elif type(val) == types.InstanceType and val.__class__.__name__ in  ('PARAMETRE','PARAMETRE_EVAL'):
-          txt = txt + i*','+ str(val) 
+              txt=txt + sep + str(val)
         else: 
         else: 
-           txt = txt + i*','+ myrepr.repr(val)
-        i=1
+           if isinstance(val,tuple):
+              texteVal='('
+              for i in val :
+                  if isinstance(i, bytes) : texteVal = texteVal +"'"+str(i)+"'," 
+                  else : texteVal = texteVal + str(i)+','
+              texteVal=texteVal[:-1]+')'
+           else : 
+              if isinstance(val,bytes): texteVal="'"+str(val)+"'"
+              else :texteVal=str(val)
+           txt = txt + sep+ texteVal 
+
+##        if len(txt) > 200:
+##            #ligne trop longue, on tronque
+##            txt=txt+" ..."
+##            break
+        sep=','
+      # cas des listes de tuples de longueur 1
+      if isinstance(val,tuple) and len(self.valeur) == 1 : txt=txt+','
       txt=txt+')'
       txt=txt+')'
-    elif isinstance(self.valeur,ASSD): 
-      # Cas des ASSD
-      txt=self.getval()
-    elif type(self.valeur) == types.InstanceType and self.valeur.__class__.__name__ in  ('PARAMETRE','PARAMETRE_EVAL'):
-      # Cas des PARAMETRES
-      txt=str(self.valeur)
     else:
       # Traitement des autres cas
     else:
       # Traitement des autres cas
-      txt = myrepr.repr(self.valeur)
+      txt = str(self.valeur)
 
     # txt peut etre une longue chaine sur plusieurs lignes.
     # Il est possible de tronquer cette chaine au premier \n et 
 
     # txt peut etre une longue chaine sur plusieurs lignes.
     # Il est possible de tronquer cette chaine au premier \n et 
@@ -126,76 +146,86 @@ class MCSIMP(I_OBJECT.OBJECT):
 
   def getval(self):
     """ 
 
   def getval(self):
     """ 
-       Retourne une chaîne de caractère représentant la valeur de self 
+       Retourne une chaine de caractere representant la valeur de self 
     """
     val=self.valeur
     """
     val=self.valeur
-    if type(val) == types.FloatType : 
+    if type(val) == float : 
       clefobj=self.GetNomConcept()
       clefobj=self.GetNomConcept()
-      if self.jdc.appli.dict_reels.has_key(clefobj):
-        if self.jdc.appli.dict_reels[clefobj].has_key(val):
-           return self.jdc.appli.dict_reels[clefobj][val]
-    if type(val) != types.TupleType :
+      if clefobj in self.jdc.appli.appliEficas.dict_reels :
+        if val in self.jdc.appli.appliEficas.appliEficas.dict_reels[clefobj] :
+           return self.jdc.appli.appliEficas.dict_reels[clefobj][val]
+    if type(val) != tuple :
       try:
         return val.get_name()
       except:
         return val
     else :
       try:
         return val.get_name()
       except:
         return val
     else :
+      if val ==() or val == [] : return val
       s='( '
       for item in val :
         try :
           s=s+item.get_name()+','
         except:
       s='( '
       for item in val :
         try :
           s=s+item.get_name()+','
         except:
-          s=s+`item`+','
+          s=s+repr(item)+','
       s=s+' )'
       return s
 
       s=s+' )'
       return s
 
+  def wait_bool(self):
+      for typ in self.definition.type:
+          try :
+            if typ == bool: return True
+          except :
+            pass
+      return False
+
   def wait_co(self):
     """
   def wait_co(self):
     """
-        Méthode booléenne qui retourne 1 si l'objet attend un objet ASSD 
+        Methode booleenne qui retourne 1 si l'objet attend un objet ASSD 
         qui n'existe pas encore (type CO()), 0 sinon
     """
     for typ in self.definition.type:
         qui n'existe pas encore (type CO()), 0 sinon
     """
     for typ in self.definition.type:
-      if type(typ) == types.ClassType :
+      if type(typ) == type or isinstance(typ,type):
         if issubclass(typ,CO) :
            return 1
     return 0
 
   def wait_assd(self):
     """ 
         if issubclass(typ,CO) :
            return 1
     return 0
 
   def wait_assd(self):
     """ 
-        Méthode booléenne qui retourne 1 si le MCS attend un objet de type ASSD 
-        ou dérivé, 0 sinon
+        Methode booleenne qui retourne 1 si le MCS attend un objet de type ASSD 
+        ou derive, 0 sinon
     """
     for typ in self.definition.type:
     """
     for typ in self.definition.type:
-      if type(typ) == types.ClassType :
+      if type(typ) == type or isinstance(typ,type):
         if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
           return 1
     return 0
 
   def wait_assd_or_geom(self):
     """ 
         if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
           return 1
     return 0
 
   def wait_assd_or_geom(self):
     """ 
-         Retourne 1 si le mot-clé simple attend un objet de type
+         Retourne 1 si le mot-cle simple attend un objet de type
          assd, ASSD, geom ou GEOM
          Retourne 0 dans le cas contraire
     """
     for typ in self.definition.type:
          assd, ASSD, geom ou GEOM
          Retourne 0 dans le cas contraire
     """
     for typ in self.definition.type:
-      if type(typ) == types.ClassType :
+      if type(typ) == type or isinstance(typ,type):
         if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
           return 1
     return 0
 
   def wait_geom(self):
     """ 
         if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
           return 1
     return 0
 
   def wait_geom(self):
     """ 
-         Retourne 1 si le mot-clé simple attend un objet de type GEOM
+         Retourne 1 si le mot-cle simple attend un objet de type GEOM
          Retourne 0 dans le cas contraire
     """
     for typ in self.definition.type:
          Retourne 0 dans le cas contraire
     """
     for typ in self.definition.type:
-      if type(typ) == types.ClassType :
+      if type(typ) == type or isinstance(typ,type):
         if issubclass(typ,GEOM) : return 1
     return 0
 
         if issubclass(typ,GEOM) : return 1
     return 0
 
+
   def wait_TXM(self):
     """ 
   def wait_TXM(self):
     """ 
-         Retourne 1 si le mot-clé simple attend un objet de type TXM
+         Retourne 1 si le mot-cle simple attend un objet de type TXM
          Retourne 0 dans le cas contraire
     """
     for typ in self.definition.type:
          Retourne 0 dans le cas contraire
     """
     for typ in self.definition.type:
@@ -207,9 +237,9 @@ class MCSIMP(I_OBJECT.OBJECT):
     """
     if self.valeur == None:
       return []
     """
     if self.valeur == None:
       return []
-    elif type(self.valeur) == types.TupleType:
+    elif type(self.valeur) == tuple:
       return list(self.valeur)
       return list(self.valeur)
-    elif type(self.valeur) == types.ListType:
+    elif type(self.valeur) == list:
       return self.valeur
     else:
       return [self.valeur]
       return self.valeur
     else:
       return [self.valeur]
@@ -217,49 +247,61 @@ class MCSIMP(I_OBJECT.OBJECT):
   def isoblig(self):
     return self.definition.statut=='o'
 
   def isoblig(self):
     return self.definition.statut=='o'
 
+  def isImmuable(self):
+    return self.definition.homo=='constant'
+
+  def isInformation(self):
+    return self.definition.homo=='information'
+
+
+
+  def valid_val(self,valeur):
+      """
+        Verifie que la valeur passee en argument (valeur) est valide
+        sans modifier la valeur courante 
+      """
+      lval=listProto.adapt(valeur)
+      if lval is None:
+         valid=0
+         mess=tr("None n'est pas une valeur autorisee")
+      else:
+         try:
+            for val in lval:
+                self.typeProto.adapt(val)
+                self.intoProto.adapt(val)
+            self.cardProto.adapt(lval)
+            if self.definition.validators:
+                self.definition.validators.convert(lval)
+            valid,mess=1,""
+         except ValError as e:
+            mess=str(e)
+            valid=0
+      return valid,mess
+
   def valid_valeur(self,new_valeur):
       """
         Verifie que la valeur passee en argument (new_valeur) est valide
         sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
       """
   def valid_valeur(self,new_valeur):
       """
         Verifie que la valeur passee en argument (new_valeur) est valide
         sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
       """
-      old_valeur=self.valeur
-      old_val=self.val
-      self.valeur = new_valeur
-      self.val = new_valeur
-      self.state="modified"
-      validite=self.isvalid()
-      self.valeur = old_valeur
-      self.val = old_valeur
-      self.state="modified"
-      self.isvalid()
+      validite,mess=self.valid_val(new_valeur)
       return validite
 
   def valid_valeur_partielle(self,new_valeur):
       """
       return validite
 
   def valid_valeur_partielle(self,new_valeur):
       """
-        Verifie que la valeur passee en argument (new_valeur) est partiellement valide
-        sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
+        Verifie que la valeur passee en argument (new_valeur) est une liste partiellement valide
+        sans modifier la valeur courante du mot cle
       """
       """
-      old_valeur=self.valeur
-      old_val=self.val
-
-      self.valeur = new_valeur
-      self.val = new_valeur
-      self.state="modified"
-      validite=0
-      if self.isvalid():
-         validite=1
-      elif self.definition.validators :
-         validite=self.definition.validators.valide_liste_partielle(new_valeur)
-
-      if validite==0:
-         min,max=self.get_min_max()
-         if len(new_valeur) < min :
-            validite=1
-
-      self.valeur = old_valeur
-      self.val = old_valeur
-      self.state="modified"
-      self.isvalid()
+      validite=1
+      try:
+          for val in new_valeur:
+              self.typeProto.adapt(val)
+              self.intoProto.adapt(val)
+              #on ne verifie pas la cardinalite
+              if self.definition.validators:
+                  validite=self.definition.validators.valide_liste_partielle(new_valeur)
+      except ValError as e:
+          validite=0
+
       return validite
 
   def update_condition_bloc(self):
       return validite
 
   def update_condition_bloc(self):
@@ -278,18 +320,19 @@ class MCSIMP(I_OBJECT.OBJECT):
         self.valeur = new_valeur
         self.val = new_valeur
         self.update_condition_bloc()
         self.valeur = new_valeur
         self.val = new_valeur
         self.update_condition_bloc()
+        self.etape.modified()
         self.fin_modif()
         return 1
 
   def eval_valeur(self,new_valeur):
     """
         self.fin_modif()
         return 1
 
   def eval_valeur(self,new_valeur):
     """
-        Essaie d'évaluer new_valeur comme une SD, une déclaration Python 
-        ou un EVAL: Retourne la valeur évaluée (ou None) et le test de réussite (1 ou 0)
+        Essaie d'evaluer new_valeur comme une SD, une declaration Python 
+        ou un EVAL: Retourne la valeur evaluee (ou None) et le test de reussite (1 ou 0)
     """
     sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
     #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
     #print sd
     """
     sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
     #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
     #print sd
-    if sd :
+    if sd is not None:
       return sd,1
     lsd = self.jdc.cherche_list_avant(self.etape,new_valeur) 
     if lsd :
       return sd,1
     lsd = self.jdc.cherche_list_avant(self.etape,new_valeur) 
     if lsd :
@@ -302,47 +345,92 @@ class MCSIMP(I_OBJECT.OBJECT):
         objet = eval(new_valeur,d)
         return objet,1
       except Exception:
         objet = eval(new_valeur,d)
         return objet,1
       except Exception:
-       itparam=self.cherche_item_parametre(new_valeur)
-       if itparam:
-            return itparam,1
+        itparam=self.cherche_item_parametre(new_valeur)
+        if itparam:
+             return itparam,1
+        try :
+             object=eval(new_valeur.valeur,d)
+        except :
+             pass
         if CONTEXT.debug : traceback.print_exc()
         return None,0
 
         if CONTEXT.debug : traceback.print_exc()
         return None,0
 
+  def eval_val(self,new_valeur):
+    """
+       Tente d'evaluer new_valeur comme un objet du jdc (par appel a eval_val_item)
+       ou comme une liste de ces memes objets
+       Si new_valeur contient au moins un separateur (,), tente l'evaluation sur
+       la chaine splittee
+    """
+    if new_valeur in ('True','False') and 'TXM' in self.definition.type  :
+       valeur=self.eval_val_item(str(new_valeur))
+       return new_valeur
+    if type(new_valeur) in (list,tuple):
+       valeurretour=[]
+       for item in new_valeur :
+          valeurretour.append(self.eval_val_item(item))
+       return valeurretour
+    else:
+       valeur=self.eval_val_item(new_valeur)
+       return valeur
+
+  def eval_val_item(self,new_valeur):
+    """
+       Tente d'evaluer new_valeur comme un concept, un parametre, un objet Python
+       Si c'est impossible retourne new_valeur inchange
+       argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
+    """
+    if self.etape and self.etape.parent:
+       valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
+       return valeur
+    else:
+       try :
+           valeur = eval(val)
+           return valeur
+       except:
+           #traceback.print_exc()
+           return new_valeur
+           pass
+
   def cherche_item_parametre (self,new_valeur):
         try:
   def cherche_item_parametre (self,new_valeur):
         try:
-         nomparam=new_valeur[0:new_valeur.find("[")]
-         indice=new_valeur[new_valeur.find("[")+1:new_valeur.find("]")]
-         for p in self.jdc.params:
-            if p.nom == nomparam :
-               if int(indice) < len(p.get_valeurs()):
-                  itparam=parametre.ITEM_PARAMETRE(p,int(indice))
-                  return itparam
-         return None
-       except:
-         return None
+          nomparam=new_valeur[0:new_valeur.find("[")]
+          indice=new_valeur[new_valeur.find(u"[")+1:new_valeur.find(u"]")]
+          for p in self.jdc.params:
+             if p.nom == nomparam :
+                if int(indice) < len(p.get_valeurs()):
+                   itparam=parametre.ITEM_PARAMETRE(p,int(indice))
+                   return itparam
+          return None
+        except:
+          return None
 
   def update_concept(self,sd):
 
   def update_concept(self,sd):
-    if type(self.valeur) in (types.ListType,types.TupleType) :
-       if sd in self.valeur:self.fin_modif()
+    if type(self.valeur) in (list,tuple) :
+       if sd in self.valeur:
+         self.init_modif()
+         self.fin_modif()
     else:
     else:
-       if sd == self.valeur:self.fin_modif()
+       if sd == self.valeur:
+         self.init_modif()
+         self.fin_modif()
 
   def delete_concept(self,sd):
     """ 
         Inputs :
            - sd=concept detruit
         Fonction :
 
   def delete_concept(self,sd):
     """ 
         Inputs :
            - sd=concept detruit
         Fonction :
-        Met a jour la valeur du mot cle simple suite à la disparition 
+        Met a jour la valeur du mot cle simple suite a la disparition 
         du concept sd
         du concept sd
+        Attention aux matrices
     """
     """
-    #print "delete_concept",sd
-    if type(self.valeur) == types.TupleType :
+    if type(self.valeur) == tuple :
       if sd in self.valeur:
         self.init_modif()
         self.valeur=list(self.valeur)
         self.valeur.remove(sd)
         self.fin_modif()
       if sd in self.valeur:
         self.init_modif()
         self.valeur=list(self.valeur)
         self.valeur.remove(sd)
         self.fin_modif()
-    elif type(self.valeur) == types.ListType:
+    elif type(self.valeur) == list:
       if sd in self.valeur:
         self.init_modif()
         self.valeur.remove(sd)
       if sd in self.valeur:
         self.init_modif()
         self.valeur.remove(sd)
@@ -353,25 +441,34 @@ class MCSIMP(I_OBJECT.OBJECT):
         self.valeur=None
         self.val=None
         self.fin_modif()
         self.valeur=None
         self.val=None
         self.fin_modif()
+    # Glut Horrible pour les matrices ???
+    if sd.__class__.__name__== "variable":
+       for type_permis in self.definition.type:
+            #if type(type_permis) == types.InstanceType:
+            # a voir en python 3
+               if type_permis.__class__.__name__ == 'Matrice' :
+                   self.state="changed"
+                   self.isvalid()
+                  
 
   def replace_concept(self,old_sd,sd):
     """
         Inputs :
 
   def replace_concept(self,old_sd,sd):
     """
         Inputs :
-           - old_sd=concept remplacé
+           - old_sd=concept remplace
            - sd=nouveau concept
         Fonction :
         Met a jour la valeur du mot cle simple suite au remplacement 
         du concept old_sd
     """
     #print "replace_concept",old_sd,sd
            - sd=nouveau concept
         Fonction :
         Met a jour la valeur du mot cle simple suite au remplacement 
         du concept old_sd
     """
     #print "replace_concept",old_sd,sd
-    if type(self.valeur) == types.TupleType :
+    if type(self.valeur) == tuple :
       if old_sd in self.valeur:
         self.init_modif()
         self.valeur=list(self.valeur)
         i=self.valeur.index(old_sd)
         self.valeur[i]=sd
         self.fin_modif()
       if old_sd in self.valeur:
         self.init_modif()
         self.valeur=list(self.valeur)
         i=self.valeur.index(old_sd)
         self.valeur[i]=sd
         self.fin_modif()
-    elif type(self.valeur) == types.ListType:
+    elif type(self.valeur) == list:
       if old_sd in self.valeur:
         self.init_modif()
         i=self.valeur.index(old_sd)
       if old_sd in self.valeur:
         self.init_modif()
         i=self.valeur.index(old_sd)
@@ -386,25 +483,25 @@ class MCSIMP(I_OBJECT.OBJECT):
 
   def set_valeur_co(self,nom_co):
       """
 
   def set_valeur_co(self,nom_co):
       """
-          Affecte à self l'objet de type CO et de nom nom_co
+          Affecte a self l'objet de type CO et de nom nom_co
       """
       #print "set_valeur_co",nom_co
       step=self.etape.parent
       if nom_co == None or nom_co == '':
          new_objet=None
       else:
       """
       #print "set_valeur_co",nom_co
       step=self.etape.parent
       if nom_co == None or nom_co == '':
          new_objet=None
       else:
-         # Avant de créer un concept il faut s'assurer du contexte : step 
+         # Avant de creer un concept il faut s'assurer du contexte : step 
          # courant
          sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
          if sd:
          # courant
          sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
          if sd:
-            # Si un concept du meme nom existe deja dans la portée de l'étape
-            # on ne crée pas le concept
-            return 0,"un concept de meme nom existe deja"
-         # Il n'existe pas de concept de meme nom. On peut donc le créer 
-         # Il faut néanmoins que la méthode NommerSdProd de step gère les 
+            # Si un concept du meme nom existe deja dans la portee de l'etape
+            # on ne cree pas le concept
+            return 0,tr("un concept de meme nom existe deja")
+         # Il n'existe pas de concept de meme nom. On peut donc le creer 
+         # Il faut neanmoins que la methode NommerSdProd de step gere les 
          # contextes en mode editeur
          # contextes en mode editeur
-         # Normalement la méthode  du Noyau doit etre surchargée
-         # On déclare l'étape du mot clé comme etape courante pour NommerSdprod
+         # Normalement la methode  du Noyau doit etre surchargee
+         # On declare l'etape du mot cle comme etape courante pour NommerSdprod
          cs= CONTEXT.get_current_step()
          CONTEXT.unset_current_step()
          CONTEXT.set_current_step(step)
          cs= CONTEXT.get_current_step()
          CONTEXT.unset_current_step()
          CONTEXT.set_current_step(step)
@@ -415,38 +512,41 @@ class MCSIMP(I_OBJECT.OBJECT):
       self.init_modif()
       self.valeur = new_objet
       self.val = new_objet
       self.init_modif()
       self.valeur = new_objet
       self.val = new_objet
-      self.fin_modif()
-      step.reset_context()
       # On force l'enregistrement de new_objet en tant que concept produit 
       # de la macro en appelant get_type_produit avec force=1
       self.etape.get_type_produit(force=1)
       # On force l'enregistrement de new_objet en tant que concept produit 
       # de la macro en appelant get_type_produit avec force=1
       self.etape.get_type_produit(force=1)
+      self.fin_modif()
+      step.reset_context()
       #print "set_valeur_co",new_objet
       #print "set_valeur_co",new_objet
-      return 1,"Concept créé"
-       
+      return 1,tr("Concept cree")
+        
   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"
      # Attention : possible probleme avec include
      """
      #print "verif_existence_sd"
      # Attention : possible probleme avec include
-     l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()  
-     if type(self.valeur) in (types.TupleType,types.ListType) :
+     # A priori il n'y a pas de raison de retirer les concepts non existants
+     # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
+     l_sd_avant_etape = list(self.jdc.get_contexte_avant(self.etape).values())  
+     if type(self.valeur) in (tuple,list) :
        l=[]
        l=[]
-       self.init_modif()
        for sd in self.valeur:
          if isinstance(sd,ASSD) :
        for sd in self.valeur:
          if isinstance(sd,ASSD) :
-           if sd in l_sd_avant_etape :
-              l.append(sd)
-        else:
-           l.append(sd)
-       self.valeur=tuple(l)
-       self.fin_modif()
+            if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
+               l.append(sd)
+         else:
+            l.append(sd)
+       if len(l) < len(self.valeur):
+          self.init_modif()
+          self.valeur=tuple(l)
+          self.fin_modif()
      else:
        if isinstance(self.valeur,ASSD) :
      else:
        if isinstance(self.valeur,ASSD) :
-         if self.valeur not in l_sd_avant_etape :
+          if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
              self.init_modif()
              self.init_modif()
-            self.valeur = None
+             self.valeur = None
              self.fin_modif()
  
   def get_min_max(self):
              self.fin_modif()
  
   def get_min_max(self):
@@ -458,7 +558,7 @@ class MCSIMP(I_OBJECT.OBJECT):
 
   def get_type(self):
      """
 
   def get_type(self):
      """
-     Retourne le type attendu par le mot-clé simple
+     Retourne le type attendu par le mot-cle simple
      """
      return self.definition.type
 
      """
      return self.definition.type
 
@@ -474,7 +574,7 @@ class MCSIMP(I_OBJECT.OBJECT):
 
   def update_mc_global(self):
      """
 
   def update_mc_global(self):
      """
-        Met a jour les mots cles globaux enregistrés dans l'étape parente
+        Met a jour les mots cles globaux enregistres dans l'etape parente
         et dans le jdc parent.
         Un mot cle simple peut etre global. 
      """
         et dans le jdc parent.
         Un mot cle simple peut etre global. 
      """
@@ -486,115 +586,118 @@ class MCSIMP(I_OBJECT.OBJECT):
         if self.jdc:
            self.jdc.mc_globaux[self.nom]=self
 
         if self.jdc:
            self.jdc.mc_globaux[self.nom]=self
 
-#--------------------------------------------------------------------------------
-# PN : ajout pour Salome des methodes suivantes (jusqu aux méthodes surchargees)
-#--------------------------------------------------------------------------------
-  def get_salome_valeurs(self):
-       l=[]
-       if not hasattr(self,'list_salome_valeurs'):
-           self.list_salome_valeurs=[]
-       if self.list_salome_valeurs != [] :
-           for val in self.list_salome_valeurs:
-                l.append(val)
-       return l
-
-  def put_salome_valeurs(self,list):
-       self.list_salome_valeurs=[]
-       for val in list:
-           self.list_salome_valeurs.append(val)
-
-  def add_salome_valeurs(self,val):
-      if not hasattr(self,'list_salome_valeurs'):
-           self.list_salome_valeurs=[]
-      try:
-           self.list_salome_valeurs.append(val)
-      except :
-           try:
-              for uneval in val :
-                  self.list_salome_valeurs.append(uneval)
-           except :
-              pass
-
-  def has_salome_valeurs(self):
-      if not hasattr(self,'list_salome_valeurs'):
-           self.list_salome_valeurs=[]
-      if self.list_salome_valeurs != []:
-           return true
-      else:
-           return false
+  def nbrColonnes(self):
+     genea = self.get_genealogie()
+     if "VALE_C" in genea and "DEFI_FONCTION" in genea : return 3
+     if "VALE" in genea and "DEFI_FONCTION" in genea : return 2
+     return 0
 
 
-#--------------------------------------------------------------------------------
-# PN : fin ajout pour Salome 
+  def valide_item(self,item):
+      """Valide un item isole. Cet item est candidata l'ajout a la liste existante"""
+      valid=1
+      try:
+          #on verifie le type
+          self.typeProto.adapt(item)
+          #on verifie les choix possibles
+          self.intoProto.adapt(item)
+          #on ne verifie pas la cardinalite
+          if self.definition.validators:
+              valid=self.definition.validators.verif_item(item)
+      except ValError as e:
+          #traceback.print_exc()
+          valid=0
+      return valid
+
+  def verif_type(self,item):
+      """Verifie le type d'un item de liste"""
+      try:
+          #on verifie le type
+          self.typeProto.adapt(item)
+          #on verifie les choix possibles
+          self.intoProto.adapt(item)
+          #on ne verifie pas la cardinalite mais on verifie les validateurs
+          if self.definition.validators:
+              valid=self.definition.validators.verif_item(item)
+          comment=""
+          valid=1
+      except ValError as e:
+          #traceback.print_exc()
+          comment=tr(e.__str__())
+          valid=0
+      return valid,comment
+
+  def valideMatrice(self,cr):
+       #Attention, la matrice contient comme dernier tuple l ordre des variables
+       if self.valideEnteteMatrice()==False :
+           self.set_valid(0)
+           if cr == "oui" : self.cr.fatal(tr("La matrice n'a pas le bon entete"))
+           return 0
+       if self.monType.methodeCalculTaille != None :
+           MCSIMP.__dict__[self.monType.methodeCalculTaille](*(self,))
+       try :
+       #if 1 :
+           ok=0
+           if len(self.valeur) == self.monType.nbLigs +1:
+              ok=1
+              for i in range(len(self.valeur) -1):
+                  if len(self.valeur[i])!= self.monType.nbCols:
+                     ok=0
+           if ok: 
+              self.set_valid(1)
+              return 1 
+       except :
+       #else :
+            pass
+       if cr == 'oui' :
+             self.cr.fatal(tr("La matrice n'est pas une matrice %(n_lign)d sur %(n_col)d", \
+             {'n_lign': self.monType.nbLigs, 'n_col': self.monType.nbCols}))
+       self.set_valid(0)
+       return 0
+
+
+  def NbDeVariables(self):
+       listeVariables=self.jdc.get_variables(self.etape)
+       self.monType.nbLigs=len(listeVariables)
+       self.monType.nbCols=len(listeVariables)
+      
+  def valideEnteteMatrice(self):
+      if self.jdc.get_distributions(self.etape) == () or self.valeur == None : return 0
+      if self.jdc.get_distributions(self.etape) != self.valeur[0] : return 0
+      return 1
+     
+  def changeEnteteMatrice(self):
+      a=[self.jdc.get_distributions(self.etape),]
+      for t in self.valeur[1:]:
+         a.append(t)
+      self.valeur=a
+
+
+  def NbDeDistributions(self):
+       listeVariables=self.jdc.get_distributions(self.etape)
+       self.monType.nbLigs=len(listeVariables)
+       self.monType.nbCols=len(listeVariables)
+      
 #--------------------------------------------------------------------------------
  
 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
 # Elles doivent etre reintegrees des que possible
 
 
 #--------------------------------------------------------------------------------
  
 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
 # Elles doivent etre reintegrees des que possible
 
 
-  def isvalid(self,cr='non'):
-      """
-         Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
-
-           - 0 si l'objet est invalide
-           - 1 si l'objet est valide
-
-         Le paramètre cr permet de paramétrer le traitement. Si cr == 'oui'
-         la méthode construit également un comte-rendu de validation
-         dans self.cr qui doit avoir été créé préalablement.
-      """
-      if self.state == 'unchanged':
-        return self.valid
-      else:
-        valid = 1
-        v=self.valeur
-        #  verification presence
-        if self.isoblig() and v == None :
-          if cr == 'oui' :
-            self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
-          valid = 0
-
-        if v is None:
-           valid=0
-           if cr == 'oui' :
-              self.cr.fatal("None n'est pas une valeur autorisée")
-        else:
-           # type,into ...
-          if v.__class__.__name__ in ('PARAMETRE' , 'EVAL', 'ITEM_PARAMETRE','PARAMETRE_EVAL'):
-             verif_type=1
-          else:
-             verif_type=self.verif_type(val=v,cr=None)
-             # cas des tuples avec un ITEM_PARAMETRE
-              if verif_type == 0:
-                 if type(v) == types.TupleType :
-                  new_val=[]
-                  for i in v:
-                    if i.__class__.__name__  not in ('PARAMETRE','EVAL', 'ITEM_PARAMETRE','PARAMETRE_EVAL'): 
-                         new_val.append(i)
-                  if new_val != [] :
-                    verif_type=self.verif_type(val=new_val,cr=cr)
-                  else :
-                    # Cas d une liste de paramétre
-                    verif_type= 1
-                else:
-                    verif_type=self.verif_type(val=v,cr=cr)
-           valid = verif_type*self.verif_into(cr=cr)*self.verif_card(cr=cr)
-           #
-           # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
-           #
-           if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
-              if cr == 'oui' :
-                 self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
-              valid=0
-           # fin des validateurs
-           #
-       # cas d un item Parametre
-       if self.valeur.__class__.__name__ == 'ITEM_PARAMETRE':
-          valid=self.valeur.isvalid()
-          if valid == 0:
-              if cr == 'oui' :
-                self.cr.fatal(string.join( repr (self.valeur), " a un indice incorrect"))
-
-        self.set_valid(valid)
-        return self.valid
-
-
+  def verif_typeihm(self,val,cr='non'):
+      try :
+         val.eval()
+         return 1
+      except :
+         traceback.print_exc()
+         pass
+      return self.verif_type(val,cr)
+
+  def verif_typeliste(self,val,cr='non') :
+      verif=0
+      for v in val :
+        verif=verif+self.verif_typeihm(v,cr)
+      return verif
+
+  def init_modif_up(self):
+    Validation.V_MCSIMP.MCSIMP.init_modif_up(self)
+    CONNECTOR.Emit(self,"valid")