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