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