Salome HOME
PN résolution de la fiche AO2004-191
[tools/eficas.git] / Editeur / composimp.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 # Modules Python
21 import string,types,os
22 from Tkinter import *
23 import Pmw
24 from copy import copy,deepcopy
25 import traceback
26
27 # Modules Eficas
28 import Objecttreeitem
29 import prefs
30 import panels
31 import images
32 from widgets import ListeChoix
33 from widgets import FenetreDeSelection
34
35 from Noyau.N_CR import justify_text
36 from utils import substract_list
37
38       
39 class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
40   from newsimppanel import newSIMPPanel
41   panel = newSIMPPanel
42
43   def init(self) :
44       self.expandable = 0
45       self.affect_panel()
46
47
48   def affect_panel(self):
49       """
50       Cette méthode attribue le panel à l'objet pointé par self en fonction de la
51       nature de la valeur demandée pour cet objet
52       """
53       from uniquepanel import UNIQUE_Panel
54       from plusieurspanel import PLUSIEURS_Panel
55
56       #print "affect_panel : ",self.nom,self.is_list(),self.has_into(), self.get_into(None)
57
58       if self.wait_shell():
59           # l'objet attend un shell
60           from shellpanel import SHELLPanel
61           self.panel = SHELLPanel
62       elif self.has_into():
63           # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
64           if self.is_list() :
65              from plusieursintopanel import PLUSIEURS_INTO_Panel
66              self.panel = PLUSIEURS_INTO_Panel
67           else:
68              from uniqueintopanel import UNIQUE_INTO_Panel
69              self.panel = UNIQUE_INTO_Panel
70       else:
71           # l'objet prend une ou des valeurs à priori quelconques
72           if self.is_list() :
73               # on attend une liste de valeurs mais de quel type ?
74               if self.wait_assd():
75                   # on attend une liste de SD
76                   from plusieursassdpanel import PLUSIEURS_ASSD_Panel
77                   self.panel = PLUSIEURS_ASSD_Panel
78               else:
79                   # on attend une liste de valeurs de types debase (entiers, réels,...)
80                   from plusieursbasepanel import PLUSIEURS_BASE_Panel
81                   self.panel = PLUSIEURS_BASE_Panel
82           else:
83               # on n'attend qu'une seule valeur mais de quel type ?
84               if self.wait_co():
85                   # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
86                   from uniquesdcopanel import UNIQUE_SDCO_Panel
87                   self.panel = UNIQUE_SDCO_Panel
88               elif self.wait_assd():
89                   # on attend une SD
90                   from uniqueassdpanel import UNIQUE_ASSD_Panel
91                   self.panel = UNIQUE_ASSD_Panel
92               else:
93                   # on attend une valeur d'un type de base (entier,réel,...)
94                   if self.wait_complex():
95                       # on attend un complexe
96                       from uniquecomppanel import UNIQUE_COMP_Panel
97                       self.panel = UNIQUE_COMP_Panel
98                   else:
99                       # on attend un entier, un réel ou une string
100                       from uniquebasepanel import UNIQUE_BASE_Panel
101                       self.panel = UNIQUE_BASE_Panel
102       # cas particulier des fonctions
103       genea = self.get_genealogie()
104       if "VALE" in genea or "VALE_C" in genea:
105          if "DEFI_FONCTION" in genea :
106             from fonctionpanel import FONCTION_Panel
107             self.panel=FONCTION_Panel
108       #---------------------------------------------------------
109       # PN ajout pour lancement de Salome
110       #---------------------------------------------------------
111       if  self.appli.salome != 0 :
112           import panelsSalome
113
114           self.clef_fonction="SALOME"
115           for i in range(0,len( genea )) :
116              self.clef_fonction=self.clef_fonction+"_"+ genea[i]
117
118           self.select_noeud_maille=0
119           if (self.clef_fonction.find("GROUP_NO") != -1)  :
120              self.select_noeud_maille=1
121           if (self.clef_fonction.find("GROUP_MA") != -1) :
122              self.select_noeud_maille=1
123
124           recherche=panelsSalome.dict_classes_salome[self.panel]
125           if hasattr(recherche,self.clef_fonction):
126              self.panel=recherche
127           if self.select_noeud_maille==1 :
128              self.panel=recherche
129
130
131   #-----------------------------------------------
132   #
133   # Methodes liees aux informations sur le Panel
134   # ou au mot-clef simple
135   #
136   #-----------------------------------------------
137   # is_list
138   # get_into            a priori inutile --> commentee
139   # has_into
140   # wait_into           a priori inutile --> commentee
141   # GetMinMax
142   # GetMultiplicite
143   # GetIntervalle
144   # GetListeValeurs
145   # get_liste_possible
146
147   def is_list(self):
148       """
149           Cette méthode indique si le mot cle simple attend une liste (valeur de retour 1)
150           ou s'il n'en attend pas (valeur de retour 0)
151
152           Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
153           Dans le cas sans validateur, l'information est donnée par l'attribut max
154           de la definition du mot cle.
155           Dans le cas avec validateur, il faut combiner l'information précédente avec
156           celle issue de l'appel de la méthode is_list sur le validateur.On utilisera
157           l'operateur ET pour effectuer cette combinaison (AndVal).
158       """
159       is_a_list=0
160       min,max = self.GetMinMax()
161       assert (min <= max)
162       if max > 1 :
163                 is_a_list=1
164       # Dans le cas avec validateurs, pour que le mot cle soit considéré
165       # comme acceptant une liste, il faut que max soit supérieur a 1
166       # ET que la méthode is_list du validateur retourne 1. Dans les autres cas
167       # on retournera 0 (n'attend pas de liste)
168       if self.definition.validators :
169          is_a_list= self.definition.validators.is_list() * is_a_list
170       return is_a_list 
171
172   #def get_into(self,liste_courante=None):
173   #    """
174   #        Cette méthode retourne la liste de choix proposée par le mot cle. Si le mot cle ne propose
175   #        pas de liste de choix, la méthode retourne None.
176   #        L'argument d'entrée liste_courante, s'il est différent de None, donne la liste des choix déjà
177   #        effectués par l'utilisateur. Dans ce cas, la méthode get_into doit calculer la liste des choix
178   #        en en tenant compte.
179   #        Cette méthode part du principe que la relation entre into du mot clé et les validateurs est
180   #        une relation de type ET (AndVal).
181   #    """
182   #    if not self.object.definition.validators :
183   #       return self.object.definition.into
184   #    else:
185   #       return self.object.definition.validators.get_into(liste_courante,self.definition.into)
186
187   def has_into(self):
188       """
189           Cette méthode indique si le mot cle simple propose un choix (valeur de retour 1)
190           ou s'il n'en propose pas (valeur de retour 0)
191
192           Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
193           Dans le cas sans validateur, l'information est donnée par l'attribut into
194           de la definition du mot cle.
195           Dans le cas avec validateurs, pour que le mot cle soit considéré
196           comme proposant un choix, il faut que into soit présent OU
197           que la méthode has_into du validateur retourne 1. Dans les autres cas
198           on retournera 0 (ne propose pas de choix)
199       """
200       has_an_into=0
201       if self.definition.into:
202          has_an_into=1
203       elif self.definition.validators :
204          has_an_into= self.definition.validators.has_into()
205       return has_an_into
206
207 #  def wait_into(self):
208 #      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
209 #      prend ses valeurs dans un ensemble discret (into), 0 sinon """
210 #      if self.object.definition.into != None :
211 #          return 1
212 #      else:
213 #          return 0
214
215   def GetMinMax(self):
216       """ Retourne les valeurs min et max de la définition de object """
217       return self.object.get_min_max()
218
219   def GetMultiplicite(self):
220       """ A préciser.
221           Retourne la multiplicité des valeurs affectées à l'objet
222           représenté par l'item. Pour le moment retourne invariablement 1.
223       """
224       return 1
225
226   def GetIntervalle(self):
227       """ 
228            Retourne le domaine de valeur attendu par l'objet représenté 
229            par l'item.
230       """
231       return self.object.getintervalle()
232
233   def GetListeValeurs(self) :
234       """ Retourne la liste des valeurs de object """
235       return self.object.get_liste_valeurs()
236     
237   def get_liste_possible(self,listeActuelle=[]):
238       if hasattr(self.definition.validators,'into'):
239          self.get_definition().into=self.definition.validators.into 
240       valeurspossibles = self.get_definition().into
241       # CCAR : Ne serait-il pas preferable d'appeler get_into ?
242       #valeurspossibles=self.get_into(listeActuelle)
243
244       listevalideitem=[]
245       for item in valeurspossibles:
246           encorevalide=self.valide_item(item)
247           if encorevalide :
248              listevalideitem.append(item)
249       # on ne verifie pas la liste des choix si max = 1 
250       # (sinon cela enleve tous les choix possibles)
251       min,max=self.GetMinMax()
252       if max != 1 : 
253          listevalideliste=[]
254          for item in listevalideitem:
255              listetravail=[]
256              for item2 in listeActuelle : listetravail.append(item2)
257              encorevalide=self.valide_liste_partielle(item,listetravail)
258              if encorevalide :
259                 listevalideliste.append(item)
260       else :
261          listevalideliste=listevalideitem
262       return listevalideliste
263
264
265   #--------------------------------------------------
266   #
267   # Methodes liees a la validite des valeurs saisies
268   #
269   #---------------------------------------------------
270   # valide_item
271   # valide_liste_partielle
272   # valide_liste_complete
273   # info_erreur_item
274   # info_erreur_liste
275   # IsInIntervalle
276   # isvalid
277
278   def valide_item(self,item):
279       """
280         On fait un try except pour les erreurs de type (exple
281         on rentre 1 pour une chaine de caracteres
282       """
283       valide=1
284       if self.definition.validators :
285          try :
286             valide=self.definition.validators.verif_item(item)
287          except :
288             valide = 0
289       return valide
290      
291   def valide_liste_partielle(self,item,listecourante):
292       valeuravant=self.object.valeur
293       valeur=listecourante
294       valeur.append(item)
295       valeur = tuple(valeur)
296       retour=self.object.set_valeur(valeur)
297       validite=0
298       if self.object.isvalid():
299          validite=1
300       elif self.definition.validators :
301          validite=self.definition.validators.valide_liste_partielle(valeur)
302
303       if validite==0:
304          min,max=self.GetMinMax()
305          if len(valeur) < min :
306             validite=1
307       retour=self.object.set_valeur(valeuravant)
308       return validite 
309
310   def valide_liste_complete (self,valeur):
311       valeuravant=self.object.valeur
312       retour=self.object.set_valeur(valeur)
313       validite=0
314       if self.object.isvalid():
315          validite=1
316       retour=self.object.set_valeur(valeuravant)
317       return validite
318      
319   def info_erreur_item(self) :
320       commentaire=""
321       if self.definition.validators :
322          commentaire=self.definition.validators.info_erreur_item()
323       return commentaire
324       
325   def aide(self) :
326       commentaire=""
327       if self.definition.validators :
328          commentaire=self.definition.validators.aide()
329       return commentaire
330
331   def info_erreur_liste(self) :
332       commentaire=""
333       if self.definition.validators :
334          commentaire=self.definition.validators.info_erreur_liste()
335       return commentaire
336
337   def IsInIntervalle(self,valeur):
338       """ 
339           Retourne 1 si la valeur est dans l'intervalle permis par
340           l'objet représenté par l'item.
341       """
342       return self.object.isinintervalle(valeur)
343
344   def isvalid(self):
345     valide=self.object.isvalid()
346     return self.object.isvalid()
347
348   #--------------------------------------------------
349   #
350   # Autres ...
351   #
352   #---------------------------------------------------
353   # SetText     a priori inutilisee --> commentee
354   # GetIconName
355   # GetText
356   # getval     a  priori inutilisee --> commentee
357   # set_valeur_co
358   # get_sd_avant_du_bon_type
359   # verif       a  priori inutilisee --> commentee
360   # delete_valeur_co
361
362   #def SetText(self, text):
363   #  try:
364   #    value = eval(text)
365   #    self.object.setval(value)
366   #  except:
367   #    pass
368
369   def GetIconName(self):
370     if self.isvalid():
371       return "ast-green-ball"
372     elif self.object.isoblig():
373       return "ast-red-ball"
374     else:
375       return "ast-yel-ball"
376
377   def GetText(self):
378     """
379     Classe SIMPTreeItem
380     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
381     pointé par self 
382     """
383     text= self.object.GetText()
384     return text
385     
386   #def getval(self):
387   #    return self.object.getval()
388
389   def set_valeur_co(self,nom_co):
390       """
391       Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
392       """
393       return self.object.set_valeur_co(nom_co)
394       
395   def get_sd_avant_du_bon_type(self):
396       """
397       Retourne la liste des noms des SD présentes avant l'étape qui contient
398       le MCS pointé par self et du type requis par ce MCS
399       """
400       a=self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type)
401       return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
402                                                                self.object.definition.type)
403
404   #def verif(self):
405   #    pass
406
407   def delete_valeur_co(self,valeur=None):
408       """
409            Supprime la valeur du mot cle (de type CO)
410            il faut propager la destruction aux autres etapes
411       """
412       if not valeur : valeur=self.object.valeur
413       # XXX faut il vraiment appeler del_sdprod ???
414       #self.object.etape.parent.del_sdprod(valeur)
415       self.object.etape.parent.delete_concept(valeur)
416
417   #-----------------------------------------------
418   #
419   # Methodes liees au type de l objet attendu
420   #
421   #-----------------------------------------------
422   # wait_co 
423   # wait_geom
424   # wait_complex
425   # wait_reel
426   # wait_shell
427   # wait_assd
428   # GetType
429
430   def wait_co(self):
431       """
432       Méthode booléenne qui retourne 1 si l'objet pointé par self
433       attend un objet de type ASSD qui n'existe pas encore (type CO()),
434       0 sinon
435       """
436       return self.object.wait_co()
437
438   def wait_geom(self):
439       """
440       Méthode booléenne qui retourne 1 si l'objet pointé par self
441       attend un objet GEOM, 0 sinon
442       """
443       return self.object.wait_geom()
444     
445   def wait_complex(self):
446       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
447       attend un complexe, 0 sinon """
448       if 'C' in self.object.definition.type:
449           return 1
450       else:
451           return 0
452
453   def wait_reel(self):
454       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
455       attend un réel, 0 sinon """
456       if 'R' in self.object.definition.type:
457           return 1
458       else:
459           return 0
460         
461   def wait_shell(self):
462       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
463       attend un shell, 0 sinon """
464       if 'shell' in self.object.definition.type:
465           return 1
466       else:
467           return 0
468
469   def wait_assd(self):
470       """Méthode booléenne qui retourne 1 si l'objet pointé par self
471       attend un objet de type ASSD ou dérivé, 0 sinon """
472       return self.object.wait_assd()
473     
474   def GetType(self):
475       """ 
476           Retourne le type de valeur attendu par l'objet représenté par l'item.
477       """
478       return self.object.get_type()
479
480   #-----------------------------------------------------
481   #
482   # Methodes liees  a l evaluation de la valeur saisie
483   #
484   #-----------------------------------------------------
485   # eval_valeur
486   # eval_valeur_item
487   # is_CO
488   # traite_reel
489
490   def eval_valeur(self,valeur):
491       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
492       de l'objet pointé par self :
493         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
494         - retourne 'valeur' (chaîne de caractères) sinon
495         - retourne None en cas d invalidite
496         - retourne invalide si 1 des objets du tuple l est
497       """
498       validite=1
499       if type(valeur) in (types.ListType,types.TupleType) :
500          valeurretour=[]
501          for item in valeur :
502              newvaleur,validiteitem=self.eval_valeur_item(item)
503              valeurretour.append(newvaleur)
504              if validiteitem == 0:
505                 validite=0
506       else :
507          valeurretour,validite= self.eval_valeur_item(valeur)
508       if validite == 0 :
509          valeurretour = None
510       return valeurretour,validite
511
512   def eval_valeur_item(self,valeur):
513       """ Lance l'interprétation de 'valeur' qui doit ne pas etre un tuple 
514           - va retourner la valeur de retour et la validite
515             selon le type de l objet attendu
516           - traite les reels et les parametres 
517       """ 
518       if valeur==None or valeur == "" :
519          return None,0
520       validite=1
521       if self.wait_reel():
522              valeurinter = self.traite_reel(valeur)
523              valeurretour,validite= self.object.eval_valeur(valeurinter)
524       elif self.wait_geom():
525              valeurretour,validite = valeur,1
526       else :
527              valeurretour,validite= self.object.eval_valeur(valeur)
528       if validite == 0:
529          if type(valeur) == types.StringType and self.object.wait_TXM():
530             essai_valeur="'" + valeur + "'"
531             valeurretour,validite= self.object.eval_valeur(essai_valeur)
532       if hasattr(valeurretour,'__class__'):
533          if valeurretour.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
534             validite=1
535       if self.wait_co():
536          try:
537             valeurretour=Accas.CO(valeur)
538          except:
539             valeurretour=None
540             validite=0
541       # on est dans le cas où on a évalué et où on n'aurait pas du
542       if self.object.wait_TXM() :
543           if type(valeurretour) != types.StringType:
544              valeurretour=str(valeur)
545              validite=1
546       return valeurretour,validite
547       
548   def is_CO(self,valeur=None):
549       """
550          Indique si valeur est un concept produit de la macro
551          Cette méthode n'a de sens que pour un MCSIMP d'une MACRO
552          Si valeur vaut None on teste la valeur du mot cle
553       """
554       # Pour savoir si un concept est un nouveau concept de macro
555       # on regarde s'il est présent dans l'attribut sdprods de l'étape
556       # ou si son nom de classe est CO.
557       # Il faut faire les 2 tests car une macro non valide peut etre
558       # dans un etat pas tres catholique avec des CO pas encore types
559       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
560       if not valeur:valeur=self.object.valeur
561       if valeur in self.object.etape.sdprods:return 1
562       if type(valeur) is not types.InstanceType:return 0
563       if valeur.__class__.__name__ == 'CO':return 1
564       return 0
565
566   def is_param(self,valeur) :
567       for param in self.jdc.params:
568           if (repr(param) == valeur):
569              return 1
570       return 0
571
572   def traite_reel(self,valeur):
573       """
574       Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
575       ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
576       ou un EVAL ...
577       """
578       valeur = string.strip(valeur)
579       liste_reels = self.get_sd_avant_du_bon_type()
580       if valeur in liste_reels:
581           return valeur
582       if len(valeur) >= 3 :
583           if valeur[0:4] == 'EVAL' :
584               # on a trouvé un EVAL --> on retourne directement la valeur
585               return valeur
586       if string.find(valeur,'.') == -1 :
587           # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
588           if (self.is_param(valeur)):
589               return valeur
590           else:
591               return valeur+'.'
592       else:
593           return valeur
594         
595
596 import Accas
597 treeitem = SIMPTreeItem
598 objet = Accas.MCSIMP
599