Salome HOME
This commit was generated by cvs2git to track changes on a CVS vendor
[tools/eficas.git] / Ihm / I_MCCOMPO.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 """
21 """
22 import string,types
23 from copy import copy
24
25 from Noyau.N_MCLIST import MCList
26 from Noyau.N_MCSIMP import MCSIMP
27 from Noyau.N_MCFACT import MCFACT
28 from Noyau.N_MCBLOC import MCBLOC
29 import I_OBJECT
30
31 class MCCOMPO(I_OBJECT.OBJECT):
32   def getlabeltext(self):
33     """ 
34        Retourne le label de self suivant qu'il s'agit d'un MCFACT, 
35        d'un MCBLOC ou d'un MCFACT appartenant à une MCList : 
36        utilisée pour l'affichage dans l'arbre
37     """
38     objet = self.parent.get_child(self.nom)
39     # objet peut-être self ou une MCList qui contient self ...
40     if isinstance(objet,MCList) :
41       index = objet.get_index(self)+1 # + 1 à cause de la numérotation qui commence à 0
42       label = self.nom +'_'+`index`+':'
43       return label
44     else:
45       return self.nom
46
47   def get_liste_mc_ordonnee(self,liste,dico):
48     """
49        Retourne la liste ordonnée (suivant le catalogue) des mots-clés
50        d'une entité composée dont le chemin complet est donné sous forme
51        d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
52        il faut encore réarranger cette liste (certains mots-clés déjà
53        présents ne doivent plus être proposés, règles ...)
54     """
55     return self.filtre_liste_mc(self.get_liste_mc_ordonnee_brute(liste,dico))
56
57   def get_liste_mc_ordonnee_brute(self,liste,dico):
58     """
59        Retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés
60        d'une entité composée dont le chemin complet est donné sous forme
61        d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
62     """
63     for arg in liste:
64         objet_cata = dico[arg]
65         dico=objet_cata.dico
66     return objet_cata.liste
67
68   def filtre_liste_mc(self,liste_brute):
69     """ 
70        Cette méthode est appelée par EFICAS afin de présenter à 
71        l'utilisateur la liste des enfants possibles de self actualisée 
72        en fonction du contexte de self. En clair, sont supprimés de la
73        liste des possibles (fournie par la définition), les mots-clés
74        exclus par les règles de self et les mots-clés ne pouvant plus 
75        être répétés
76     """
77     liste = copy(liste_brute)
78     liste_mc_presents = self.liste_mc_presents()
79     # on enlève les mots-clés non permis par les règles
80     for regle in self.definition.regles:
81        # la méthode purge_liste est à développer pour chaque règle qui
82        # influe sur la liste de choix à proposer à l'utilisateur
83        # --> EXCLUS,UN_PARMI,PRESENT_ABSENT
84        liste = regle.purge_liste(liste,liste_mc_presents)
85     # on enlève les mots-clés dont l'occurrence est déjà atteinte
86     liste_copy = copy(liste)
87     for k in liste_copy:
88       objet = self.get_child(k,restreint = 'oui')
89       if objet != None :
90         # l'objet est déjà présent : il faut distinguer plusieurs cas
91         if isinstance(objet,MCSIMP):
92           # un mot-clé simple ne peut pas être répété
93           liste.remove(k)
94         elif isinstance(objet,MCBLOC):
95           # un bloc conditionnel ne doit pas apparaître dans la liste de choix
96           liste.remove(k)
97         elif isinstance(objet,MCFACT):
98           # un mot-clé facteur ne peut pas être répété plus de self.max fois
99           if objet.definition.max == 1:
100             liste.remove(k)
101         elif isinstance(objet,MCList):
102           try :
103             nb_occur_maxi = objet[0].definition.max
104             if len(objet) >= nb_occur_maxi:
105               liste.remove(k)
106           except:
107             pass
108         else :
109           #XXX CCAR : les MCNUPLET ne sont pas traités
110           if CONTEXT.debug : print '   ',k,' est un objet de type inconnu :',type(objet)
111       else :
112         # l'objet est absent : on enlève de la liste les blocs
113         if self.definition.entites[k].statut=='c' :
114           liste.remove(k)
115         if self.definition.entites[k].label=='BLOC':
116           liste.remove(k)
117     # Pour corriger les exces qui pourraient etre commis dans la methode purge_liste
118     # des regles, on essaie de compenser comme suit :
119     # on ajoute les mots cles facteurs presents dont l'occurence n'est pas atteinte
120     for k in liste_mc_presents:
121       if k in liste:continue
122       objet = self.get_child(k,restreint = 'oui')
123       if isinstance(objet,MCFACT):
124           # un mot-clé facteur ne peut pas être répété plus de self.max fois
125           if objet.definition.max > 1:
126              liste.append(k)
127       elif isinstance(objet,MCList):
128           nb_occur_maxi = objet[0].definition.max
129           if len(objet) < nb_occur_maxi:
130               liste.append(k)
131     return liste
132
133   def liste_mc_presents(self):
134     """ 
135        Retourne la liste des noms des mots-clés fils de self présents construite
136        à partir de self.mc_liste 
137     """
138     l=[]
139     for v in self.mc_liste:
140       k=v.nom
141       l.append(k)
142     return l
143
144   def ordonne_liste_mc(self,liste_mc_a_ordonner,liste_noms_mc_ordonnee):
145     """
146         Retourne liste_mc_a_ordonner ordonnée suivant l'ordre 
147         donné par liste_noms_mc_ordonnee
148     """
149     liste = []
150     # on transforme liste_a_ordonner en un dictionnaire (plus facile à consulter)
151     d_mc = {}
152     for mc in liste_mc_a_ordonner:
153       d_mc[mc.nom]=mc
154     # on construit la liste des objets ordonnés
155     for nom_mc in liste_noms_mc_ordonnee:
156       if d_mc.has_key(nom_mc):
157         liste.append(d_mc.get(nom_mc))
158     # on la retourne
159     return liste
160
161   def suppentite(self,objet) :
162     """ 
163         Supprime le fils 'objet' de self : 
164         Retourne 1 si la suppression a pu être effectuée,
165         Retourne 0 dans le cas contraire
166     """
167     self.init_modif()
168     if not objet in self.mc_liste:
169        # Impossible de supprimer objet. Il n'est pas dans mc_liste
170        self.fin_modif()
171        return 0
172
173     try :
174       if hasattr(objet.definition,'position'):
175           if objet.definition.position == 'global' :
176             self.delete_mc_global(objet)
177           elif objet.definition.position == 'global_jdc' :
178             self.delete_mc_global_jdc(objet)
179       self.mc_liste.remove(objet)
180       self.fin_modif()
181       return 1
182     except:
183       self.fin_modif()
184       return 0
185
186   def isoblig(self):
187     return self.definition.statut=='o'
188
189   def addentite(self,name,pos=None):
190       """ 
191           Ajoute le mot-cle name à la liste des mots-cles de
192           l'objet MCCOMPOSE
193       """
194       self.init_modif()
195       if type(name)==types.StringType :
196         # on est en mode création d'un motcle 
197         if self.ispermis(name) == 0 : return 0
198         objet=self.definition.entites[name](val=None,nom=name,parent=self)
199         if hasattr(objet.definition,'position'):
200           if objet.definition.position == 'global' :
201             self.append_mc_global(objet)
202           elif objet.definition.position == 'global_jdc' :
203             self.append_mc_global_jdc(objet)
204       else :
205         # dans ce cas on est en mode copie d'un motcle
206         objet = name
207         objet.verif_existence_sd()
208       # si un objet de même nom est déjà présent dans la liste
209       # et si l'objet est répétable
210       # il faut créer une MCList et remplacer l'objet de la liste
211       # par la MCList
212       test1 = objet.isrepetable()
213       old_obj = self.get_child(objet.nom,restreint = 'oui')
214       test2 = self.ispermis(objet)
215       #print "test1,test2=",test1,test2
216       if test1 == 0 and old_obj :
217         self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
218         self.fin_modif()
219         return 0
220       if test2 == 0:
221         self.jdc.send_message("L'objet %s ne peut être un fils de %s" %(objet.nom,self.nom))
222         self.fin_modif()
223         return 0
224       if test1 :
225         if old_obj :
226           #if not isinstance(old_obj,MCList):
227           if not old_obj.isMCList():
228             # un objet de même nom existe déjà mais ce n'est pas une MCList
229             # Il faut en créer une 
230             # L'objet existant (old_obj) est certainement un MCFACT 
231             # qui pointe vers un constructeur
232             # de MCList : definition.liste_instance
233             #print "un objet de même type existe déjà"
234             index = self.mc_liste.index(old_obj)
235             #XXX remplacé par definition.list_instance : new_obj = MCList()
236             new_obj = old_obj.definition.list_instance()
237             new_obj.init(objet.nom,self)
238             new_obj.append(old_obj)
239             new_obj.append(objet)
240             # Il ne faut pas oublier de reaffecter le parent d'obj
241             objet.reparent(self)
242             self.mc_liste.remove(old_obj)
243             self.mc_liste.insert(index,new_obj)
244             self.fin_modif()
245             return new_obj
246           else :
247             # une liste d'objets de même type existe déjà
248             #print "une liste d'objets de même type existe déjà"
249             old_obj.append(objet)
250             # Il ne faut pas oublier de reaffecter le parent d'obj
251             objet.reparent(self)
252             self.fin_modif()
253             return old_obj
254       if pos == None :
255         self.mc_liste.append(objet)
256       else :
257         self.mc_liste.insert(pos,objet)
258       # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
259       objet.reparent(self)
260       self.fin_modif()
261       return objet
262
263   def ispermis(self,fils):
264     """ 
265         Retourne 1 si l'objet de nom nom_fils 
266         est bien permis, cad peut bien être un fils de self, 
267         Retourne 0 sinon 
268     """
269     if type(fils) == types.StringType :
270       # on veut juste savoir si self peut avoir un fils de nom 'fils'
271       if self.definition.entites.has_key(fils):
272         return 1
273       else :
274         return 0
275     elif type(fils) == types.InstanceType:
276       # fils est un objet (commande,mcf,mclist)
277       # on est dans le cas d'une tentative de copie de l'objet
278       # on veut savoir si l'objet peut bien être un fils de self :
279       # la vérification du nom de suffit pas (plusieurs commandes
280       # ont le même mot-clé facteur AFFE ... et c'est l'utilisateur
281       # qui choisit le père d'où un risque d'erreur)
282       if not self.definition.entites.has_key(fils.nom):
283         return 0
284       else:
285         if fils.parent.nom != self.nom : return 0
286       return 1
287
288   def liste_mc_presents(self):
289     """ 
290          Retourne la liste des noms des mots-clés fils de self présents 
291          construite à partir de self.mc_liste 
292     """
293     l=[]
294     for v in self.mc_liste:
295       k=v.nom
296       l.append(k)
297     return l
298
299   def delete_concept(self,sd):
300     """ 
301         Inputs :
302            sd=concept detruit
303         Fonction :
304            Mettre a jour les fils de l objet suite à la disparition du
305            concept sd
306            Seuls les mots cles simples MCSIMP font un traitement autre que 
307            de transmettre aux fils
308     """
309     for child in self.mc_liste :
310       child.delete_concept(sd)
311
312   def delete_mc_global(self,mc):
313     """ 
314         Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape 
315     """
316     etape = self.get_etape()
317     if etape :
318       nom = mc.nom
319       del etape.mc_globaux[nom]
320
321   def delete_mc_global_jdc(self,mc):
322     """ 
323         Supprime le mot-clé mc de la liste des mots-clés globaux du jdc 
324     """
325     nom = mc.nom
326     del self.jdc.mc_globaux[nom]
327
328   def copy(self):
329     """ Retourne une copie de self """
330     objet = self.makeobjet()
331     # FR : attention !!! avec makeobjet, objet a le même parent que self
332     # ce qui n'est pas du tout bon dans le cas d'une copie !!!!!!!
333     # FR : peut-on passer par là autrement que dans le cas d'une copie ???
334     # FR --> je suppose que non
335     # XXX CCAR : le pb c'est qu'on vérifie ensuite quel parent avait l'objet
336     # Il me semble preferable de changer le parent a la fin quand la copie est acceptee
337     objet.valeur = copy(self.valeur)
338     objet.val = copy(self.val)
339     objet.mc_liste=[]
340     for obj in self.mc_liste:
341       new_obj = obj.copy()
342       new_obj.reparent(objet)
343       objet.mc_liste.append(new_obj)
344     return objet
345
346   def get_sd_utilisees(self):
347     """ 
348         Retourne la liste des concepts qui sont utilisés à l'intérieur de self
349         ( comme valorisation d'un MCS) 
350     """
351     l=[]
352     for child in self.mc_liste:
353       l.extend(child.get_sd_utilisees())
354     return l
355
356   def get_liste_mc_inconnus(self):
357      """
358      Retourne la liste des mots-clés inconnus dans self
359      """
360      l_mc = []
361      if self.reste_val != {}:
362         for k,v in self.reste_val.items() :
363             l_mc.append([self,k,v])
364      for child in self.mc_liste :
365         if child.isvalid() : continue
366         l_child = child.get_liste_mc_inconnus()
367         for mc in l_child:
368            l = [self]
369            l.extend(mc)
370            l_mc.append(l)
371      return l_mc
372
373   def verif_condition_bloc(self):
374     """ 
375         Evalue les conditions de tous les blocs fils possibles 
376         (en fonction du catalogue donc de la définition) de self
377         et retourne deux listes :
378         - la première contient les noms des blocs à rajouter
379         - la seconde contient les noms des blocs à supprimer
380     """
381     liste_ajouts = []
382     liste_retraits = []
383     dict = self.cree_dict_valeurs(self.mc_liste)
384     for k,v in self.definition.entites.items():
385       #dict = self.cree_dict_valeurs(self.mc_liste)
386       if v.label=='BLOC' :
387         if v.verif_presence(dict) :
388           # le bloc doit être présent
389           if not self.get_child(k,restreint = 'oui'):
390             # le bloc n'est pas présent et il doit être créé
391             liste_ajouts.append(k)
392         else :
393           # le bloc doit être absent
394           if self.get_child(k,restreint = 'oui'):
395             # le bloc est présent : il faut l'enlever
396             liste_retraits.append(k)
397     return liste_ajouts,liste_retraits
398
399   def reparent(self,parent):
400      """
401          Cette methode sert a reinitialiser la parente de l'objet
402      """
403      self.parent=parent
404      self.jdc=parent.get_jdc_root()
405      self.etape=parent.etape
406      for mocle in self.mc_liste:
407         mocle.reparent(self)
408
409   def verif_existence_sd(self):
410      """
411         Vérifie que les structures de données utilisées dans self existent bien dans le contexte
412         avant étape, sinon enlève la référence à ces concepts
413      """
414      for motcle in self.mc_liste :
415          motcle.verif_existence_sd()