Salome HOME
F.R: composimp.py : dans méthode select_in_file, ajout d'un paramètre manquant dans le
[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     return liste
99
100   def liste_mc_presents(self):
101     """ 
102        Retourne la liste des noms des mots-clés fils de self présents construite
103        à partir de self.mc_liste 
104     """
105     l=[]
106     for v in self.mc_liste:
107       k=v.nom
108       l.append(k)
109     return l
110
111   def ordonne_liste_mc(self,liste_mc_a_ordonner,liste_noms_mc_ordonnee):
112     """
113         Retourne liste_mc_a_ordonner ordonnée suivant l'ordre 
114         donné par liste_noms_mc_ordonnee
115     """
116     liste = []
117     # on transforme liste_a_ordonner en un dictionnaire (plus facile à consulter)
118     d_mc = {}
119     for mc in liste_mc_a_ordonner:
120       d_mc[mc.nom]=mc
121     # on construit la liste des objets ordonnés
122     for nom_mc in liste_noms_mc_ordonnee:
123       if d_mc.has_key(nom_mc):
124         liste.append(d_mc.get(nom_mc))
125     # on la retourne
126     return liste
127
128   def suppentite(self,objet) :
129     """ 
130         Supprime le fils 'objet' de self : 
131         Retourne 1 si la suppression a pu être effectuée,
132         Retourne 0 dans le cas contraire
133     """
134     self.init_modif()
135     if not objet in self.mc_liste:
136        # Impossible de supprimer objet. Il n'est pas dans mc_liste
137        self.fin_modif()
138        return 0
139
140     try :
141       if hasattr(objet.definition,'position'):
142           if objet.definition.position == 'global' :
143             self.delete_mc_global(objet)
144           elif objet.definition.position == 'global_jdc' :
145             self.delete_mc_global_jdc(objet)
146       self.mc_liste.remove(objet)
147       self.fin_modif()
148       return 1
149     except:
150       self.fin_modif()
151       return 0
152
153   def isoblig(self):
154     return self.definition.statut=='o'
155
156   def addentite(self,name,pos=None):
157       """ 
158           Ajoute le mot-cle name à la liste des mots-cles de
159           l'objet MCCOMPOSE
160       """
161       self.init_modif()
162       if type(name)==types.StringType :
163         # on est en mode création d'un motcle 
164         if self.ispermis(name) == 0 : return 0
165         objet=self.definition.entites[name](val=None,nom=name,parent=self)
166         if hasattr(objet.definition,'position'):
167           if objet.definition.position == 'global' :
168             self.append_mc_global(objet)
169           elif objet.definition.position == 'global_jdc' :
170             self.append_mc_global_jdc(objet)
171       else :
172         # dans ce cas on est en mode copie d'un motcle
173         objet = name
174         objet.verif_existence_sd()
175       # si un objet de même nom est déjà présent dans la liste
176       # et si l'objet est répétable
177       # il faut créer une MCList et remplacer l'objet de la liste
178       # par la MCList
179       test1 = objet.isrepetable()
180       old_obj = self.get_child(objet.nom,restreint = 'oui')
181       test2 = self.ispermis(objet)
182       #print "test1,test2=",test1,test2
183       if test1 == 0 and old_obj :
184         self.jdc.send_message("L'objet %s ne peut pas être répété" %objet.nom)
185         self.fin_modif()
186         return 0
187       if test2 == 0:
188         self.jdc.send_message("L'objet %s ne peut être un fils de %s" %(objet.nom,self.nom))
189         self.fin_modif()
190         return 0
191       if test1 :
192         if old_obj :
193           #if not isinstance(old_obj,MCList):
194           if not old_obj.isMCList():
195             # un objet de même nom existe déjà mais ce n'est pas une MCList
196             # Il faut en créer une 
197             # L'objet existant (old_obj) est certainement un MCFACT 
198             # qui pointe vers un constructeur
199             # de MCList : definition.liste_instance
200             #print "un objet de même type existe déjà"
201             index = self.mc_liste.index(old_obj)
202             #XXX remplacé par definition.list_instance : new_obj = MCList()
203             new_obj = old_obj.definition.list_instance()
204             new_obj.init(objet.nom,self)
205             new_obj.append(old_obj)
206             new_obj.append(objet)
207             # Il ne faut pas oublier de reaffecter le parent d'obj
208             objet.reparent(self)
209             self.mc_liste.remove(old_obj)
210             self.mc_liste.insert(index,new_obj)
211             self.fin_modif()
212             return new_obj
213           else :
214             # une liste d'objets de même type existe déjà
215             #print "une liste d'objets de même type existe déjà"
216             old_obj.append(objet)
217             # Il ne faut pas oublier de reaffecter le parent d'obj
218             objet.reparent(self)
219             self.fin_modif()
220             return old_obj
221       if pos == None :
222         self.mc_liste.append(objet)
223       else :
224         self.mc_liste.insert(pos,objet)
225       # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
226       objet.reparent(self)
227       self.fin_modif()
228       return objet
229
230   def ispermis(self,fils):
231     """ 
232         Retourne 1 si l'objet de nom nom_fils 
233         est bien permis, cad peut bien être un fils de self, 
234         Retourne 0 sinon 
235     """
236     if type(fils) == types.StringType :
237       # on veut juste savoir si self peut avoir un fils de nom 'fils'
238       if self.definition.entites.has_key(fils):
239         return 1
240       else :
241         return 0
242     elif type(fils) == types.InstanceType:
243       # fils est un objet (commande,mcf,mclist)
244       # on est dans le cas d'une tentative de copie de l'objet
245       # on veut savoir si l'objet peut bien être un fils de self :
246       # la vérification du nom de suffit pas (plusieurs commandes
247       # ont le même mot-clé facteur AFFE ... et c'est l'utilisateur
248       # qui choisit le père d'où un risque d'erreur)
249       if not self.definition.entites.has_key(fils.nom):
250         return 0
251       else:
252         if fils.parent.nom != self.nom : return 0
253       return 1
254
255   def liste_mc_presents(self):
256     """ 
257          Retourne la liste des noms des mots-clés fils de self présents 
258          construite à partir de self.mc_liste 
259     """
260     l=[]
261     for v in self.mc_liste:
262       k=v.nom
263       l.append(k)
264     return l
265
266   def delete_concept(self,sd):
267     """ 
268         Inputs :
269            sd=concept detruit
270         Fonction :
271            Mettre a jour les fils de l objet suite à la disparition du
272            concept sd
273            Seuls les mots cles simples MCSIMP font un traitement autre que 
274            de transmettre aux fils
275     """
276     for child in self.mc_liste :
277       child.delete_concept(sd)
278
279   def delete_mc_global(self,mc):
280     """ 
281         Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape 
282     """
283     etape = self.get_etape()
284     if etape :
285       nom = mc.nom
286       del etape.mc_globaux[nom]
287
288   def delete_mc_global_jdc(self,mc):
289     """ 
290         Supprime le mot-clé mc de la liste des mots-clés globaux du jdc 
291     """
292     nom = mc.nom
293     del self.jdc.mc_globaux[nom]
294
295   def copy(self):
296     """ Retourne une copie de self """
297     objet = self.makeobjet()
298     # FR : attention !!! avec makeobjet, objet a le même parent que self
299     # ce qui n'est pas du tout bon dans le cas d'une copie !!!!!!!
300     # FR : peut-on passer par là autrement que dans le cas d'une copie ???
301     # FR --> je suppose que non
302     # XXX CCAR : le pb c'est qu'on vérifie ensuite quel parent avait l'objet
303     # Il me semble preferable de changer le parent a la fin quand la copie est acceptee
304     objet.valeur = copy(self.valeur)
305     objet.val = copy(self.val)
306     objet.mc_liste=[]
307     for obj in self.mc_liste:
308       new_obj = obj.copy()
309       new_obj.reparent(objet)
310       objet.mc_liste.append(new_obj)
311     return objet
312
313   def get_sd_utilisees(self):
314     """ 
315         Retourne la liste des concepts qui sont utilisés à l'intérieur de self
316         ( comme valorisation d'un MCS) 
317     """
318     l=[]
319     for child in self.mc_liste:
320       l.extend(child.get_sd_utilisees())
321     return l
322
323   def get_liste_mc_inconnus(self):
324      """
325      Retourne la liste des mots-clés inconnus dans self
326      """
327      l_mc = []
328      if self.reste_val != {}:
329         for k,v in self.reste_val.items() :
330             l_mc.append([self,k,v])
331      for child in self.mc_liste :
332         if child.isvalid() : continue
333         l_child = child.get_liste_mc_inconnus()
334         if l_child :
335            l = [self]
336            l.extend(l_child)
337            l_mc.append(l)
338      return l_mc
339
340   def verif_condition_bloc(self):
341     """ 
342         Evalue les conditions de tous les blocs fils possibles 
343         (en fonction du catalogue donc de la définition) de self
344         et retourne deux listes :
345         - la première contient les noms des blocs à rajouter
346         - la seconde contient les noms des blocs à supprimer
347     """
348     liste_ajouts = []
349     liste_retraits = []
350     dict = self.cree_dict_valeurs(self.mc_liste)
351     for k,v in self.definition.entites.items():
352       #dict = self.cree_dict_valeurs(self.mc_liste)
353       if v.label=='BLOC' :
354         if v.verif_presence(dict) :
355           # le bloc doit être présent
356           if not self.get_child(k,restreint = 'oui'):
357             # le bloc n'est pas présent et il doit être créé
358             liste_ajouts.append(k)
359         else :
360           # le bloc doit être absent
361           if self.get_child(k,restreint = 'oui'):
362             # le bloc est présent : il faut l'enlever
363             liste_retraits.append(k)
364     return liste_ajouts,liste_retraits
365
366   def reparent(self,parent):
367      """
368          Cette methode sert a reinitialiser la parente de l'objet
369      """
370      self.parent=parent
371      self.jdc=parent.get_jdc_root()
372      self.etape=parent.etape
373      for mocle in self.mc_liste:
374         mocle.reparent(self)
375
376   def verif_existence_sd(self):
377      """
378         Vérifie que les structures de données utilisées dans self existent bien dans le contexte
379         avant étape, sinon enlève la référence à ces concepts
380      """
381      for motcle in self.mc_liste :
382          motcle.verif_existence_sd()