Salome HOME
bug 53033
[tools/eficas.git] / Ihm / I_MCCOMPO.py
index 28bb21f1b8ef16260866641ae442c663eed744e4..c629886a94121949e3093c2218706026d777897c 100644 (file)
@@ -1,34 +1,35 @@
 # -*- 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
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
-# ======================================================================
 """
 """
-import string,types
+import string,types,sys
 from copy import copy
 import traceback
 
+from Extensions.i18n import tr
 from Noyau.N_MCLIST import MCList
 from Noyau.N_MCSIMP import MCSIMP
 from Noyau.N_MCFACT import MCFACT
 from Noyau.N_MCBLOC import MCBLOC
 import I_OBJECT
+import Validation
 
 import CONNECTOR
 
@@ -36,62 +37,70 @@ class MCCOMPO(I_OBJECT.OBJECT):
   def getlabeltext(self):
     """ 
        Retourne le label de self 
-       utilisé pour l'affichage dans l'arbre
+       utilise pour l'affichage dans l'arbre
     """
     return self.nom
 
   def get_liste_mc_ordonnee(self,liste,dico):
     """
-       Retourne la liste ordonnée (suivant le catalogue) des mots-clés
-       d'une entité composée dont le chemin complet est donné sous forme
+       Retourne la liste ordonnee (suivant le catalogue) des mots-cles
+       d'une entite composee dont le chemin complet est donne sous forme
        d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
-       il faut encore réarranger cette liste (certains mots-clés déjà
-       présents ne doivent plus être proposés, règles ...)
+       il faut encore rearranger cette liste (certains mots-cles deja
+       presents ne doivent plus etre proposes, regles ...)
     """
     return self.filtre_liste_mc(self.get_liste_mc_ordonnee_brute(liste,dico))
 
   def get_liste_mc_ordonnee_brute(self,liste,dico):
     """
-       Retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés
-       d'une entité composée dont le chemin complet est donné sous forme
+       Retourne la liste ordonnee (suivant le catalogue) BRUTE des mots-cles
+       d'une entite composee dont le chemin complet est donne sous forme
        d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
     """
     for arg in liste:
         objet_cata = dico[arg]
         dico=objet_cata.entites
+        l=[]
+        specifique=0
+        for obj in dico.keys() :
+            if not(hasattr(dico[obj],'cache')) or dico[obj].cache==0 :
+               l.append(obj)
+            else :
+               specifique=1
+        if specifique == 1 : return l    
     return objet_cata.ordre_mc
 
   def filtre_liste_mc(self,liste_brute):
     """ 
-       Cette méthode est appelée par EFICAS afin de présenter à 
-       l'utilisateur la liste des enfants possibles de self actualisé
-       en fonction du contexte de self. En clair, sont supprimés de la
-       liste des possibles (fournie par la définition), les mots-clés
-       exclus par les règles de self et les mots-clés ne pouvant plus 
-       être répétés
+       Cette methode est appelee par EFICAS afin de presenter a 
+       l'utilisateur la liste des enfants possibles de self actualise
+       en fonction du contexte de self. En clair, sont supprimes de la
+       liste des possibles (fournie par la definition), les mots-cles
+       exclus par les regles de self et les mots-cles ne pouvant plus 
+       etre repetes
     """
     liste = copy(liste_brute)
     liste_mc_presents = self.liste_mc_presents()
-    # on enlève les mots-clés non permis par les règles
+    # on enleve les mots-cles non permis par les regles
     for regle in self.definition.regles:
-       # la méthode purge_liste est à développer pour chaque règle qui
-       # influe sur la liste de choix à proposer à l'utilisateur
+       # la methode purge_liste est a developper pour chaque regle qui
+       # influe sur la liste de choix a proposer a l'utilisateur
        # --> EXCLUS,UN_PARMI,PRESENT_ABSENT
        liste = regle.purge_liste(liste,liste_mc_presents)
-    # on enlève les mots-clés dont l'occurrence est déjà atteinte
+    # on enleve les mots-cles dont l'occurrence est deja atteinte
     liste_copy = copy(liste)
     for k in liste_copy:
       objet = self.get_child(k,restreint = 'oui')
       if objet != None :
-        # l'objet est déjà présent : il faut distinguer plusieurs cas
+        # l'objet est deja present : il faut distinguer plusieurs cas
         if isinstance(objet,MCSIMP):
-          # un mot-clé simple ne peut pas être répété
+          # un mot-cle simple ne peut pas etre repete
           liste.remove(k)
         elif isinstance(objet,MCBLOC):
-          # un bloc conditionnel ne doit pas apparaître dans la liste de choix
+          # un bloc conditionnel ne doit pas apparaitre dans la liste de choix
           liste.remove(k)
         elif isinstance(objet,MCFACT):
-          # un mot-clé facteur ne peut pas être répété plus de self.max fois
+          # un mot-cle facteur ne peut pas etre repete plus de self.max fois
           if objet.definition.max == 1:
             liste.remove(k)
         elif isinstance(objet,MCList):
@@ -102,10 +111,10 @@ class MCCOMPO(I_OBJECT.OBJECT):
           except:
             pass
         else :
-          #XXX CCAR : les MCNUPLET ne sont pas traités
+          #XXX CCAR : les MCNUPLET ne sont pas traites
           if CONTEXT.debug : print '   ',k,' est un objet de type inconnu :',type(objet)
       else :
-        # l'objet est absent : on enlève de la liste les blocs
+        # l'objet est absent : on enleve de la liste les blocs
         if self.definition.entites[k].statut=='c' :
           liste.remove(k)
         if self.definition.entites[k].label=='BLOC':
@@ -117,7 +126,7 @@ class MCCOMPO(I_OBJECT.OBJECT):
       if k in liste:continue
       objet = self.get_child(k,restreint = 'oui')
       if isinstance(objet,MCFACT):
-          # un mot-clé facteur ne peut pas être répété plus de self.max fois
+          # un mot-cle facteur ne peut pas etre repete plus de self.max fois
           if objet.definition.max > 1:
              liste.append(k)
       elif isinstance(objet,MCList):
@@ -128,8 +137,8 @@ class MCCOMPO(I_OBJECT.OBJECT):
 
   def liste_mc_presents(self):
     """ 
-       Retourne la liste des noms des mots-clés fils de self présents construite
-       à partir de self.mc_liste 
+       Retourne la liste des noms des mots-cles fils de self presents construite
+       a partir de self.mc_liste 
     """
     l=[]
     for v in self.mc_liste:
@@ -140,7 +149,7 @@ class MCCOMPO(I_OBJECT.OBJECT):
   def get_index_child(self,nom_fils):
       """
         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
-        Permet de savoir à quelle position il faut ajouter un nouveau mot-clé
+        Permet de savoir a quelle position il faut ajouter un nouveau mot-cle
       """
       cata_ordonne = self.jdc.cata_ordonne_dico
       liste_noms_mc_ordonnee = self.get_liste_mc_ordonnee_brute(self.get_genealogie(),cata_ordonne)
@@ -154,15 +163,15 @@ class MCCOMPO(I_OBJECT.OBJECT):
           
   def ordonne_liste_mc(self,liste_mc_a_ordonner,liste_noms_mc_ordonnee):
     """
-        Retourne liste_mc_a_ordonner ordonnée suivant l'ordre 
-        donné par liste_noms_mc_ordonnee
+        Retourne liste_mc_a_ordonner ordonnee suivant l'ordre 
+        donne par liste_noms_mc_ordonnee
     """
     liste = []
-    # on transforme liste_a_ordonner en un dictionnaire (plus facile à consulter)
+    # on transforme liste_a_ordonner en un dictionnaire (plus facile a consulter)
     d_mc = {}
     for mc in liste_mc_a_ordonner:
       d_mc[mc.nom]=mc
-    # on construit la liste des objets ordonnés
+    # on construit la liste des objets ordonnes
     for nom_mc in liste_noms_mc_ordonnee:
       if d_mc.has_key(nom_mc):
         liste.append(d_mc.get(nom_mc))
@@ -172,85 +181,68 @@ class MCCOMPO(I_OBJECT.OBJECT):
   def suppentite(self,objet) :
     """ 
         Supprime le fils 'objet' de self : 
-        Retourne 1 si la suppression a pu être effectuée,
+        Retourne 1 si la suppression a pu etre effectuee,
         Retourne 0 dans le cas contraire
     """
-    self.init_modif()
     if not objet in self.mc_liste:
        # Impossible de supprimer objet. Il n'est pas dans mc_liste
-       self.fin_modif()
        return 0
 
-    try :
-      self.mc_liste.remove(objet)
-      CONNECTOR.Emit(self,"supp",objet)
-
-      if hasattr(objet.definition,'position'):
-         if objet.definition.position == 'global' :
-            self.delete_mc_global(objet)
-            self.etape.deep_update_condition_bloc()
-         elif objet.definition.position == 'global_jdc' :
-            self.delete_mc_global_jdc(objet)
-            self.jdc.deep_update_condition_bloc()
-      else:
-         self.update_condition_bloc()
-
-      self.fin_modif()
-      return 1
-    except:
-      self.fin_modif()
-      return 0
+    self.init_modif()
+    self.mc_liste.remove(objet)
+    CONNECTOR.Emit(self,"supp",objet)
+    objet.delete_mc_global()
+    objet.update_condition_bloc()
+    objet.supprime()
+    self.etape.modified()
+    self.fin_modif()
+    return 1
 
   def isoblig(self):
       return 0
 
   def addentite(self,name,pos=None):
       """ 
-          Ajoute le mot-cle name à la liste des mots-cles de
+          Ajoute le mot-cle name a la liste des mots-cles de
           l'objet MCCOMPOSE
       """
-      #print "I_MCCOMPO.addentite",name,pos
       self.init_modif()
       if type(name)==types.StringType :
-        # on est en mode création d'un motcle 
+        # on est en mode creation d'un motcle 
         if self.ispermis(name) == 0 : return 0
         objet=self.definition.entites[name](val=None,nom=name,parent=self)
-        if hasattr(objet.definition,'position'):
-          if objet.definition.position == 'global' :
-            self.append_mc_global(objet)
-          elif objet.definition.position == 'global_jdc' :
-            self.append_mc_global_jdc(objet)
       else :
         # dans ce cas on est en mode copie d'un motcle
         objet = name
-       # Appel de la methode qui fait le menage dans les references
-       # sur les concepts produits (verification que les concepts existent
-       # dans le contexte de la commande courante).
-       objet.verif_existence_sd()
+        # Appel de la methode qui fait le menage dans les references
+        # sur les concepts produits (verification que les concepts existent
+        # dans le contexte de la commande courante).
+        objet.verif_existence_sd()
 
       # On verifie que l'ajout d'objet est autorise
       if self.ispermis(objet) == 0:
-        self.jdc.send_message("L'objet %s ne peut être un fils de %s" %(objet.nom,
-                                                                       self.nom))
+        self.jdc.appli.affiche_alerte(tr("Erreur"),
+                                      tr("L'objet %(v_1)s ne peut  etre un fils de %(v_2)s",\
+                                      {'v_1': objet.nom, 'v_2': self.nom}))
         self.fin_modif()
         return 0
 
       # On cherche s'il existe deja un mot cle de meme nom
       old_obj = self.get_child(objet.nom,restreint = 'oui')
-      #print "addentite",old_obj
-      #if old_obj:print "addentite",old_obj.isrepetable(),old_obj.isMCList(),old_obj.ajout_possible()
       if not old_obj :
-         #print self.mc_liste,objet
+         # on normalize l'objet
+         objet=objet.normalize()
          # Le mot cle n'existe pas encore. On l'ajoute a la position
-        # demandee (pos)
+         # demandee (pos)
          if pos == None :
            self.mc_liste.append(objet)
          else :
            self.mc_liste.insert(pos,objet)
-         #print self.mc_liste,objet
          # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
          objet.reparent(self)
          CONNECTOR.Emit(self,"add",objet)
+         objet.update_mc_global()
+         objet.update_condition_bloc()
          self.fin_modif()
          return objet
       else:
@@ -258,38 +250,19 @@ class MCCOMPO(I_OBJECT.OBJECT):
          # on cree une liste d'objets. Dans le cas contraire,
          # on emet un message d'erreur.
          if not old_obj.isrepetable():
-            self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
+            self.jdc.appli.affiche_alerte(tr("Erreur"),tr("L'objet %s ne peut pas etre repete", objet.nom))
             self.fin_modif()
             return 0
          else:
-            if not old_obj.isMCList():
-               # un objet de même nom existe déjà mais ce n'est pas une MCList
-               # Il faut en créer une 
-               # L'objet existant (old_obj) est certainement un MCFACT 
-               # qui pointe vers un constructeur
-               # de MCList : definition.liste_instance
-               index = self.mc_liste.index(old_obj)
-               new_obj = old_obj.definition.list_instance()
-               new_obj.init(objet.nom,self)
-               new_obj.append(old_obj)
-               new_obj.append(objet)
-               # Il ne faut pas oublier de reaffecter le parent d'obj
-               objet.reparent(self)
-               self.mc_liste.remove(old_obj)
-               CONNECTOR.Emit(self,"supp",old_obj)
-               self.mc_liste.insert(index,new_obj)
-               CONNECTOR.Emit(self,"add",new_obj)
-               self.fin_modif()
-               return new_obj
-            else :
-               # une liste d'objets de même type existe déjà
-               old_obj.addentite(objet)
-               return old_obj
+            # une liste d'objets de meme type existe deja
+            old_obj.addentite(objet)
+            self.fin_modif()
+            return old_obj
 
   def ispermis(self,fils):
     """ 
         Retourne 1 si l'objet de nom nom_fils 
-        est bien permis, cad peut bien être un fils de self, 
+        est bien permis, cad peut bien etre un fils de self, 
         Retourne 0 sinon 
     """
     if type(fils) == types.StringType :
@@ -301,10 +274,10 @@ class MCCOMPO(I_OBJECT.OBJECT):
     elif type(fils) == types.InstanceType:
       # fils est un objet (commande,mcf,mclist)
       # on est dans le cas d'une tentative de copie de l'objet
-      # on veut savoir si l'objet peut bien être un fils de self :
-      # la vérification du nom de suffit pas (plusieurs commandes
-      # ont le même mot-clé facteur AFFE ... et c'est l'utilisateur
-      # qui choisit le père d'où un risque d'erreur)
+      # on veut savoir si l'objet peut bien etre un fils de self :
+      # la verification du nom de suffit pas (plusieurs commandes
+      # ont le meme mot-cle facteur AFFE ... et c'est l'utilisateur
+      # qui choisit le pere d'ou un risque d'erreur)
       if not self.definition.entites.has_key(fils.nom):
         return 0
       else:
@@ -320,7 +293,7 @@ class MCCOMPO(I_OBJECT.OBJECT):
         Inputs :
            - sd=concept detruit
         Fonction :
-        Mettre a jour les fils de l objet suite à la disparition du
+        Mettre a jour les fils de l objet suite a la disparition du
         concept sd
         Seuls les mots cles simples MCSIMP font un traitement autre que 
         de transmettre aux fils
@@ -340,37 +313,21 @@ class MCCOMPO(I_OBJECT.OBJECT):
     for child in self.mc_liste :
       child.replace_concept(old_sd,sd)
 
-  def delete_mc_global(self,mc):
-    """ 
-        Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape 
-    """
-    etape = self.get_etape()
-    if etape :
-      nom = mc.nom
-      del etape.mc_globaux[nom]
-
-  def delete_mc_global_jdc(self,mc):
-    """ 
-        Supprime le mot-clé mc de la liste des mots-clés globaux du jdc 
-    """
-    nom = mc.nom
-    del self.jdc.mc_globaux[nom]
-
   def get_liste_mc_inconnus(self):
      """
-     Retourne la liste des mots-clés inconnus dans self
+     Retourne la liste des mots-cles inconnus dans self
      """
      l_mc = []
      if self.reste_val != {}:
         for k,v in self.reste_val.items() :
-           l_mc.append([self,k,v])
+            l_mc.append([self,k,v])
      for child in self.mc_liste :
         if child.isvalid() : continue
         l_child = child.get_liste_mc_inconnus()
         for mc in l_child:
-          l = [self]
-          l.extend(mc)
-          l_mc.append(l)
+           l = [self]
+           l.extend(mc)
+           l_mc.append(l)
      return l_mc
 
   def deep_update_condition_bloc(self):
@@ -378,17 +335,23 @@ class MCCOMPO(I_OBJECT.OBJECT):
         Parcourt l'arborescence des mcobject et realise l'update 
         des blocs conditionnels par appel de la methode update_condition_bloc
      """
-     #print "deep_update_condition_bloc",self
-     self.update_condition_bloc()
+     self._update_condition_bloc()
      for mcobj in self.mc_liste:
         if hasattr(mcobj,"deep_update_condition_bloc"):
            mcobj.deep_update_condition_bloc()
 
   def update_condition_bloc(self):
+     """
+        Realise l'update des blocs conditionnels fils de self
+        et propage au parent
+     """
+     self._update_condition_bloc()
+     if self.parent:self.parent.update_condition_bloc()
+
+  def _update_condition_bloc(self):
      """
         Realise l'update des blocs conditionnels fils de self
      """
-     #print "update_condition_bloc",self
      dict = self.cree_dict_condition(self.mc_liste,condition=1)
      for k,v in self.definition.entites.items():
         if v.label != 'BLOC' :continue
@@ -396,24 +359,24 @@ class MCCOMPO(I_OBJECT.OBJECT):
         bloc=self.get_child(k,restreint = 'oui')
         presence=v.verif_presence(dict,globs)
         if presence and not bloc:
-           # le bloc doit être présent
-           # mais le bloc n'est pas présent et il doit être créé
+           # le bloc doit etre present
+           # mais le bloc n'est pas present et il doit etre cree
            #print "AJOUT BLOC",k
            pos=self.get_index_child(k)
            self.addentite(k,pos)
         if not presence and bloc:
-           # le bloc devrait être absent
-           # le bloc est présent : il faut l'enlever
+           # le bloc devrait etre absent
+           # le bloc est present : il faut l'enlever
            #print "SUPPRESSION BLOC",k,bloc
            self.suppentite(bloc)
 
   def verif_condition_bloc(self):
     """ 
         Evalue les conditions de tous les blocs fils possibles 
-        (en fonction du catalogue donc de la définition) de self
+        (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
     """
     liste_ajouts = []
     liste_retraits = []
@@ -422,21 +385,44 @@ class MCCOMPO(I_OBJECT.OBJECT):
       if v.label=='BLOC' :
         globs= self.jdc and self.jdc.condition_context or {}
         if v.verif_presence(dict,globs):
-          # le bloc doit être présent
+          # le bloc doit etre present
           if not self.get_child(k,restreint = 'oui'):
-            # le bloc n'est pas présent et il doit être créé
+            # le bloc n'est pas present et il doit etre cree
             liste_ajouts.append(k)
         else :
-          # le bloc doit être absent
+          # le bloc doit etre absent
           if self.get_child(k,restreint = 'oui'):
-            # le bloc est présent : il faut l'enlever
+            # le bloc est present : il faut l'enlever
             liste_retraits.append(k)
     return liste_ajouts,liste_retraits
 
   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 reference a ces concepts
      """
      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 parente 
+        et dans le jdc parent.
+        Un mot cle compose ne peut pas etre global. Il se contente de passer
+        la requete a ses fils.
+     """
+     for motcle in self.mc_liste :
+         motcle.update_mc_global()
+
+  def delete_mc_global(self):
+     for motcle in self.mc_liste :
+         motcle.delete_mc_global()
+     try :
+         motcle.update_mc_global()
+     except :
+       pass
+
+  def init_modif_up(self):
+    Validation.V_MCCOMPO.MCCOMPO.init_modif_up(self)
+    CONNECTOR.Emit(self,"valid")
+