+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2013 EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
"""
"""
-import string,types
+from __future__ import absolute_import
+from __future__ import print_function
+import string,types,sys
from copy import copy
+import traceback
-from Noyau.N_MCLIST import MCList
+import Validation
+from Extensions.i18n import tr
from Noyau.N_MCSIMP import MCSIMP
from Noyau.N_MCFACT import MCFACT
from Noyau.N_MCBLOC import MCBLOC
-import I_OBJECT
+from Noyau.N_MCLIST import MCList
+from . import I_OBJECT
+
+from . import CONNECTOR
class MCCOMPO(I_OBJECT.OBJECT):
def getlabeltext(self):
"""
- Retourne le label de self suivant qu'il s'agit d'un MCFACT,
- d'un MCBLOC ou d'un MCFACT appartenant à une MCList :
- utilisée pour l'affichage dans l'arbre
+ Retourne le label de self
+ utilise pour l'affichage dans l'arbre
"""
- objet = self.parent.get_child(self.nom)
- # objet peut-être self ou une MCList qui contient self ...
- if isinstance(objet,MCList) :
- index = objet.get_index(self)+1 # + 1 à cause de la numérotation qui commence à 0
- label = self.nom +'_'+`index`+':'
- return label
- else:
- return self.nom
+ 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.dico
- return objet_cata.liste
+ dico=objet_cata.entites
+ l=[]
+ specifique=0
+ for obj in list(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ée
- 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 actualisee
+ 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):
except:
pass
else :
- #XXX CCAR : les MCNUPLET ne sont pas traités
- if CONTEXT.debug : print ' ',k,' est un objet de type inconnu :',type(objet)
+ #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':
liste.remove(k)
+ # Pour corriger les exces qui pourraient etre commis dans la methode purge_liste
+ # des regles, on essaie de compenser comme suit :
+ # on ajoute les mots cles facteurs presents dont l'occurence n'est pas atteinte
+ for k in liste_mc_presents:
+ if k in liste:continue
+ objet = self.get_child(k,restreint = 'oui')
+ if isinstance(objet,MCFACT):
+ # 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):
+ nb_occur_maxi = objet[0].definition.max
+ if len(objet) < nb_occur_maxi:
+ liste.append(k)
return liste
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:
l.append(k)
return l
+ 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 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)
+ liste_noms_mc_presents = self.liste_mc_presents()
+ index=0
+ for nom in liste_noms_mc_ordonnee:
+ if nom == nom_fils:break
+ if nom not in liste_noms_mc_presents :continue
+ index=index+1
+ return index
+
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):
+ if nom_mc in d_mc:
liste.append(d_mc.get(nom_mc))
# on la retourne
return liste
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 :
- if hasattr(objet.definition,'position'):
- if objet.definition.position == 'global' :
- self.delete_mc_global(objet)
- elif objet.definition.position == 'global_jdc' :
- self.delete_mc_global_jdc(objet)
- self.mc_liste.remove(objet)
- 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 self.definition.statut=='o'
+ 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
"""
self.init_modif()
- if type(name)==types.StringType :
+ if type(name)==bytes :
+ # 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
- # si un objet de même nom est déjà présent dans la liste
- # et si l'objet est répétable
- # il faut créer une MCList et remplacer l'objet de la liste
- # par la MCList
- test1 = objet.isrepetable()
- old_obj = self.get_child(objet.nom,restreint = 'oui')
- test2 = self.ispermis(objet)
- #print "test1,test2=",test1,test2
- if test1 == 0 and old_obj :
- self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
- self.fin_modif()
- return 0
- if test2 == 0:
- self.jdc.send_message("L'objet %s ne peut être un fils de %s" %(objet.nom,self.nom))
+ # 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.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
- if test1 :
- if old_obj :
- #if not isinstance(old_obj,MCList):
- 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
- #print "un objet de même type existe déjà"
- index = self.mc_liste.index(old_obj)
- #XXX remplacé par definition.list_instance : new_obj = MCList()
- 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)
- self.mc_liste.insert(index,new_obj)
+
+ # On cherche s'il existe deja un mot cle de meme nom
+ old_obj = self.get_child(objet.nom,restreint = 'oui')
+ if not old_obj :
+ # on normalize l'objet
+ objet=objet.normalize()
+ # Le mot cle n'existe pas encore. On l'ajoute a la position
+ # demandee (pos)
+ if pos == None :
+ self.mc_liste.append(objet)
+ else :
+ self.mc_liste.insert(pos,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:
+ # Le mot cle existe deja. Si le mot cle est repetable,
+ # on cree une liste d'objets. Dans le cas contraire,
+ # on emet un message d'erreur.
+ if not old_obj.isrepetable():
+ self.jdc.appli.affiche_alerte(tr("Erreur"),tr("L'objet %s ne peut pas etre repete", objet.nom))
self.fin_modif()
- return new_obj
- else :
- # une liste d'objets de même type existe déjà
- #print "une liste d'objets de même type existe déjà"
- old_obj.append(objet)
- # Il ne faut pas oublier de reaffecter le parent d'obj
- objet.reparent(self)
+ return 0
+ else:
+ # une liste d'objets de meme type existe deja
+ old_obj.addentite(objet)
self.fin_modif()
return old_obj
- if pos == None :
- self.mc_liste.append(objet)
- else :
- self.mc_liste.insert(pos,objet)
- # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
- objet.reparent(self)
- self.fin_modif()
- return objet
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 :
+ if type(fils) == bytes :
# on veut juste savoir si self peut avoir un fils de nom 'fils'
- if self.definition.entites.has_key(fils):
+ if fils in self.definition.entites:
return 1
else :
return 0
- elif type(fils) == types.InstanceType:
+ #elif type(fils) == types.InstanceType:
+ elif isinstance(fils,object):
# 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)
- if not self.definition.entites.has_key(fils.nom):
+ # 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 fils.nom in self.definition.entites:
return 0
else:
if fils.parent.nom != self.nom : return 0
return 1
- 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
- """
- l=[]
- for v in self.mc_liste:
- k=v.nom
- l.append(k)
- return l
+ def update_concept(self,sd):
+ for child in self.mc_liste :
+ child.update_concept(sd)
def delete_concept(self,sd):
"""
Inputs :
- sd=concept detruit
+ - sd=concept detruit
Fonction :
- Mettre a jour les fils de l objet suite à la disparition du
- concept sd
- Seuls les mots cles simples MCSIMP font un traitement autre que
- de transmettre aux fils
+ Mettre a jour les 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
"""
for child in self.mc_liste :
child.delete_concept(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
+ def replace_concept(self,old_sd,sd):
"""
- nom = mc.nom
- del self.jdc.mc_globaux[nom]
-
- def copy(self):
- """ Retourne une copie de self """
- objet = self.makeobjet()
- # FR : attention !!! avec makeobjet, objet a le même parent que self
- # ce qui n'est pas du tout bon dans le cas d'une copie !!!!!!!
- # FR : peut-on passer par là autrement que dans le cas d'une copie ???
- # FR --> je suppose que non
- # XXX CCAR : le pb c'est qu'on vérifie ensuite quel parent avait l'objet
- # Il me semble preferable de changer le parent a la fin quand la copie est acceptee
- objet.valeur = copy(self.valeur)
- objet.val = copy(self.val)
- objet.mc_liste=[]
- for obj in self.mc_liste:
- new_obj = obj.copy()
- new_obj.reparent(objet)
- objet.mc_liste.append(new_obj)
- return objet
-
- def get_sd_utilisees(self):
- """
- Retourne la liste des concepts qui sont utilisés à l'intérieur de self
- ( comme valorisation d'un MCS)
+ Inputs :
+ - old_sd=concept remplace
+ - sd = nouveau concept
+ Fonction :
+ Mettre a jour les fils de l objet suite au remplacement du
+ concept old_sd
"""
- l=[]
- for child in self.mc_liste:
- l.extend(child.get_sd_utilisees())
- return l
+ for child in self.mc_liste :
+ child.replace_concept(old_sd,sd)
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()
- if l_child :
- l = [self]
- l.extend(l_child)
- l_mc.append(l)
+ for mc in l_child:
+ l = [self]
+ l.extend(mc)
+ l_mc.append(l)
return l_mc
+ def deep_update_condition_bloc(self):
+ """
+ Parcourt l'arborescence des mcobject et realise l'update
+ des blocs conditionnels par appel de la methode 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
+ """
+ dict = self.cree_dict_condition(self.mc_liste,condition=1)
+ for k,v in self.definition.entites.items():
+ if v.label != 'BLOC' :continue
+ globs= self.jdc and self.jdc.condition_context or {}
+ bloc=self.get_child(k,restreint = 'oui')
+ presence=v.verif_presence(dict,globs)
+ if presence and not bloc:
+ # 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 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 = []
- dict = self.cree_dict_valeurs(self.mc_liste)
+ dict = self.cree_dict_condition(self.mc_liste,condition=1)
for k,v in self.definition.entites.items():
- #dict = self.cree_dict_valeurs(self.mc_liste)
if v.label=='BLOC' :
- if v.verif_presence(dict) :
- # le bloc doit être présent
+ globs= self.jdc and self.jdc.condition_context or {}
+ if v.verif_presence(dict,globs):
+ # 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 reparent(self,parent):
+ def verif_existence_sd(self):
"""
- Cette methode sert a reinitialiser la parente de l'objet
+ Verifie que les structures de donnees utilisees dans self existent bien dans le contexte
+ avant etape, sinon enleve la reference a ces concepts
"""
- self.parent=parent
- self.jdc=parent.get_jdc_root()
- self.etape=parent.etape
- for mocle in self.mc_liste:
- mocle.reparent(self)
+ 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")
+