1 # -*- coding: utf-8 -*-
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
26 from Noyau.N_MCLIST import MCList
27 from Noyau.N_MCSIMP import MCSIMP
28 from Noyau.N_MCFACT import MCFACT
29 from Noyau.N_MCBLOC import MCBLOC
32 class MCCOMPO(I_OBJECT.OBJECT):
33 def getlabeltext(self):
35 Retourne le label de self
36 utilisé pour l'affichage dans l'arbre
40 def get_liste_mc_ordonnee(self,liste,dico):
42 Retourne la liste ordonnée (suivant le catalogue) des mots-clés
43 d'une entité composée dont le chemin complet est donné sous forme
44 d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
45 il faut encore réarranger cette liste (certains mots-clés déjà
46 présents ne doivent plus être proposés, règles ...)
48 return self.filtre_liste_mc(self.get_liste_mc_ordonnee_brute(liste,dico))
50 def get_liste_mc_ordonnee_brute(self,liste,dico):
52 Retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés
53 d'une entité composée dont le chemin complet est donné sous forme
54 d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
57 objet_cata = dico[arg]
58 dico=objet_cata.entites
59 return objet_cata.ordre_mc
61 def filtre_liste_mc(self,liste_brute):
63 Cette méthode est appelée par EFICAS afin de présenter à
64 l'utilisateur la liste des enfants possibles de self actualisée
65 en fonction du contexte de self. En clair, sont supprimés de la
66 liste des possibles (fournie par la définition), les mots-clés
67 exclus par les règles de self et les mots-clés ne pouvant plus
70 liste = copy(liste_brute)
71 liste_mc_presents = self.liste_mc_presents()
72 # on enlève les mots-clés non permis par les règles
73 for regle in self.definition.regles:
74 # la méthode purge_liste est à développer pour chaque règle qui
75 # influe sur la liste de choix à proposer à l'utilisateur
76 # --> EXCLUS,UN_PARMI,PRESENT_ABSENT
77 liste = regle.purge_liste(liste,liste_mc_presents)
78 # on enlève les mots-clés dont l'occurrence est déjà atteinte
79 liste_copy = copy(liste)
81 objet = self.get_child(k,restreint = 'oui')
83 # l'objet est déjà présent : il faut distinguer plusieurs cas
84 if isinstance(objet,MCSIMP):
85 # un mot-clé simple ne peut pas être répété
87 elif isinstance(objet,MCBLOC):
88 # un bloc conditionnel ne doit pas apparaître dans la liste de choix
90 elif isinstance(objet,MCFACT):
91 # un mot-clé facteur ne peut pas être répété plus de self.max fois
92 if objet.definition.max == 1:
94 elif isinstance(objet,MCList):
96 nb_occur_maxi = objet[0].definition.max
97 if len(objet) >= nb_occur_maxi:
102 #XXX CCAR : les MCNUPLET ne sont pas traités
103 if CONTEXT.debug : print ' ',k,' est un objet de type inconnu :',type(objet)
105 # l'objet est absent : on enlève de la liste les blocs
106 if self.definition.entites[k].statut=='c' :
108 if self.definition.entites[k].label=='BLOC':
110 # Pour corriger les exces qui pourraient etre commis dans la methode purge_liste
111 # des regles, on essaie de compenser comme suit :
112 # on ajoute les mots cles facteurs presents dont l'occurence n'est pas atteinte
113 for k in liste_mc_presents:
114 if k in liste:continue
115 objet = self.get_child(k,restreint = 'oui')
116 if isinstance(objet,MCFACT):
117 # un mot-clé facteur ne peut pas être répété plus de self.max fois
118 if objet.definition.max > 1:
120 elif isinstance(objet,MCList):
121 nb_occur_maxi = objet[0].definition.max
122 if len(objet) < nb_occur_maxi:
126 def liste_mc_presents(self):
128 Retourne la liste des noms des mots-clés fils de self présents construite
129 à partir de self.mc_liste
132 for v in self.mc_liste:
137 def ordonne_liste_mc(self,liste_mc_a_ordonner,liste_noms_mc_ordonnee):
139 Retourne liste_mc_a_ordonner ordonnée suivant l'ordre
140 donné par liste_noms_mc_ordonnee
143 # on transforme liste_a_ordonner en un dictionnaire (plus facile à consulter)
145 for mc in liste_mc_a_ordonner:
147 # on construit la liste des objets ordonnés
148 for nom_mc in liste_noms_mc_ordonnee:
149 if d_mc.has_key(nom_mc):
150 liste.append(d_mc.get(nom_mc))
154 def suppentite(self,objet) :
156 Supprime le fils 'objet' de self :
157 Retourne 1 si la suppression a pu être effectuée,
158 Retourne 0 dans le cas contraire
161 if not objet in self.mc_liste:
162 # Impossible de supprimer objet. Il n'est pas dans mc_liste
167 if hasattr(objet.definition,'position'):
168 if objet.definition.position == 'global' :
169 self.delete_mc_global(objet)
170 elif objet.definition.position == 'global_jdc' :
171 self.delete_mc_global_jdc(objet)
172 self.mc_liste.remove(objet)
182 def addentite(self,name,pos=None):
184 Ajoute le mot-cle name à la liste des mots-cles de
188 if type(name)==types.StringType :
189 # on est en mode création d'un motcle
190 if self.ispermis(name) == 0 : return 0
191 objet=self.definition.entites[name](val=None,nom=name,parent=self)
192 if hasattr(objet.definition,'position'):
193 if objet.definition.position == 'global' :
194 self.append_mc_global(objet)
195 elif objet.definition.position == 'global_jdc' :
196 self.append_mc_global_jdc(objet)
198 # dans ce cas on est en mode copie d'un motcle
200 # Appel de la methode qui fait le menage dans les references
201 # sur les concepts produits (verification que les concepts existent
202 # dans le contexte de la commande courante).
203 objet.verif_existence_sd()
205 # On verifie que l'ajout d'objet est autorise
206 if self.ispermis(objet) == 0:
207 self.jdc.send_message("L'objet %s ne peut être un fils de %s" %(objet.nom,
212 # On cherche s'il existe deja un mot cle de meme nom
213 old_obj = self.get_child(objet.nom,restreint = 'oui')
215 # Le mot cle n'existe pas encore. On l'ajoute a la position
218 self.mc_liste.append(objet)
220 self.mc_liste.insert(pos,objet)
221 # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
226 # Le mot cle existe deja. Si le mot cle est repetable,
227 # on cree une liste d'objets. Dans le cas contraire,
228 # on emet un message d'erreur.
229 if not old_obj.isrepetable():
230 self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
234 if not old_obj.isMCList():
235 # un objet de même nom existe déjà mais ce n'est pas une MCList
236 # Il faut en créer une
237 # L'objet existant (old_obj) est certainement un MCFACT
238 # qui pointe vers un constructeur
239 # de MCList : definition.liste_instance
240 index = self.mc_liste.index(old_obj)
241 new_obj = old_obj.definition.list_instance()
242 new_obj.init(objet.nom,self)
243 new_obj.append(old_obj)
244 new_obj.append(objet)
245 # Il ne faut pas oublier de reaffecter le parent d'obj
247 self.mc_liste.remove(old_obj)
248 self.mc_liste.insert(index,new_obj)
252 # une liste d'objets de même type existe déjà
253 if not old_obj.ajout_possible():
254 self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
259 old_obj.append(objet)
260 # Il ne faut pas oublier de reaffecter le parent d'obj
265 def ispermis(self,fils):
267 Retourne 1 si l'objet de nom nom_fils
268 est bien permis, cad peut bien être un fils de self,
271 if type(fils) == types.StringType :
272 # on veut juste savoir si self peut avoir un fils de nom 'fils'
273 if self.definition.entites.has_key(fils):
277 elif type(fils) == types.InstanceType:
278 # fils est un objet (commande,mcf,mclist)
279 # on est dans le cas d'une tentative de copie de l'objet
280 # on veut savoir si l'objet peut bien être un fils de self :
281 # la vérification du nom de suffit pas (plusieurs commandes
282 # ont le même mot-clé facteur AFFE ... et c'est l'utilisateur
283 # qui choisit le père d'où un risque d'erreur)
284 if not self.definition.entites.has_key(fils.nom):
287 if fils.parent.nom != self.nom : return 0
290 def liste_mc_presents(self):
292 Retourne la liste des noms des mots-clés fils de self présents
293 construite à partir de self.mc_liste
296 for v in self.mc_liste:
301 def delete_concept(self,sd):
306 Mettre a jour les fils de l objet suite à la disparition du
308 Seuls les mots cles simples MCSIMP font un traitement autre que
309 de transmettre aux fils
311 for child in self.mc_liste :
312 child.delete_concept(sd)
314 def replace_concept(self,old_sd,sd):
317 - old_sd=concept remplace
318 - sd = nouveau concept
320 Mettre a jour les fils de l objet suite au remplacement du
323 for child in self.mc_liste :
324 child.replace_concept(old_sd,sd)
326 def delete_mc_global(self,mc):
328 Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape
330 etape = self.get_etape()
333 del etape.mc_globaux[nom]
335 def delete_mc_global_jdc(self,mc):
337 Supprime le mot-clé mc de la liste des mots-clés globaux du jdc
340 del self.jdc.mc_globaux[nom]
342 def get_liste_mc_inconnus(self):
344 Retourne la liste des mots-clés inconnus dans self
347 if self.reste_val != {}:
348 for k,v in self.reste_val.items() :
349 l_mc.append([self,k,v])
350 for child in self.mc_liste :
351 if child.isvalid() : continue
352 l_child = child.get_liste_mc_inconnus()
359 def verif_condition_bloc(self):
361 Evalue les conditions de tous les blocs fils possibles
362 (en fonction du catalogue donc de la définition) de self
363 et retourne deux listes :
364 - la première contient les noms des blocs à rajouter
365 - la seconde contient les noms des blocs à supprimer
369 dict = self.cree_dict_condition(self.mc_liste)
370 for k,v in self.definition.entites.items():
372 globs= self.jdc and self.jdc.condition_context or {}
373 if v.verif_presence(dict,globs):
374 # le bloc doit être présent
375 if not self.get_child(k,restreint = 'oui'):
376 # le bloc n'est pas présent et il doit être créé
377 liste_ajouts.append(k)
379 # le bloc doit être absent
380 if self.get_child(k,restreint = 'oui'):
381 # le bloc est présent : il faut l'enlever
382 liste_retraits.append(k)
383 return liste_ajouts,liste_retraits
385 def verif_existence_sd(self):
387 Vérifie que les structures de données utilisées dans self existent bien dans le contexte
388 avant étape, sinon enlève la référence à ces concepts
390 for motcle in self.mc_liste :
391 motcle.verif_existence_sd()