Salome HOME
PN bug notation scientifique
[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       valeurs=self.object.get_liste_valeurs()
237       try :
238         if "R" in self.object.definition.type:
239            clef=self.object.GetNomConcept()
240            if self.appli.dict_reels.has_key(clef):
241               if type(valeurs) == types.TupleType:
242                  valeurs_reelles=[]
243                  for val in valeurs :
244                     if self.appli.dict_reels[clef].has_key(val) : 
245                        valeurs_reelles.append(self.appli.dict_reels[clef][val])
246                     else :
247                        valeurs_reelles.append(val)
248               else :
249                  if self.appli.dict_reels[clef].has_key(valeurs):
250                     valeurs_reelles=self.appli.dict_reels[clef][valeurs]
251               valeurs=valeurs_reelles
252       except :
253         pass
254       return valeurs
255     
256   def get_liste_possible(self,listeActuelle=[]):
257       if hasattr(self.definition.validators,'into'):
258          self.get_definition().into=self.definition.validators.into 
259       valeurspossibles = self.get_definition().into
260       # CCAR : Ne serait-il pas preferable d'appeler get_into ?
261       #valeurspossibles=self.get_into(listeActuelle)
262
263       listevalideitem=[]
264       for item in valeurspossibles:
265           encorevalide=self.valide_item(item)
266           if encorevalide :
267              listevalideitem.append(item)
268       # on ne verifie pas la liste des choix si max = 1 
269       # (sinon cela enleve tous les choix possibles)
270       min,max=self.GetMinMax()
271       if max != 1 : 
272          listevalideliste=[]
273          for item in listevalideitem:
274              listetravail=[]
275              for item2 in listeActuelle : listetravail.append(item2)
276              encorevalide=self.valide_liste_partielle(item,listetravail)
277              if encorevalide :
278                 listevalideliste.append(item)
279       else :
280          listevalideliste=listevalideitem
281       return listevalideliste
282
283   def get_liste_param_possible(self):
284   # 
285       liste_param=[]
286       for param in self.object.jdc.params:
287           encorevalide=self.valide_item(param.valeur)
288           if encorevalide:
289              type_param=param.valeur.__class__.__name__
290              for typ in self.definition.type:
291                  if typ=='R':
292                      liste_param.append(param)
293                  if typ=='I' and type_param=='int':
294                      liste_param.append(param)
295                  if typ=='TXM' and type_param=='str':
296                      liste_param.append(repr(param))
297       return liste_param
298
299   #--------------------------------------------------
300   #
301   # Methodes liees a la validite des valeurs saisies
302   #
303   #---------------------------------------------------
304   # valide_item
305   # valide_liste_partielle
306   # valide_liste_complete
307   # info_erreur_item
308   # info_erreur_liste
309   # IsInIntervalle
310   # isvalid
311
312   def valide_item(self,item):
313       """
314         On fait un try except pour les erreurs de type (exple
315         on rentre 1 pour une chaine de caracteres
316       """
317       valide=1
318       if self.definition.validators :
319          try :
320             valide=self.definition.validators.verif_item(item)
321          except :
322             valide = 0
323       return valide
324      
325   def valide_liste_partielle(self,item,listecourante):
326       valeuravant=self.object.valeur
327       valeur=listecourante
328       valeur.append(item)
329       valeur = tuple(valeur)
330       retour=self.object.set_valeur(valeur)
331       validite=0
332       if self.object.isvalid():
333          validite=1
334       elif self.definition.validators :
335          validite=self.definition.validators.valide_liste_partielle(valeur)
336
337       if validite==0:
338          min,max=self.GetMinMax()
339          if len(valeur) < min :
340             validite=1
341       retour=self.object.set_valeur(valeuravant)
342       return validite 
343
344   def valide_liste_complete (self,valeur):
345       valeuravant=self.object.valeur
346       retour=self.object.set_valeur(valeur)
347       validite=0
348       if self.object.isvalid():
349          validite=1
350       retour=self.object.set_valeur(valeuravant)
351       return validite
352      
353   def info_erreur_item(self) :
354       commentaire=""
355       if self.definition.validators :
356          commentaire=self.definition.validators.info_erreur_item()
357       return commentaire
358       
359   def aide(self) :
360       commentaire=""
361       if self.definition.validators :
362          commentaire=self.definition.validators.aide()
363       return commentaire
364
365   def info_erreur_liste(self) :
366       commentaire=""
367       if self.definition.validators :
368          commentaire=self.definition.validators.info_erreur_liste()
369       return commentaire
370
371   def IsInIntervalle(self,valeur):
372       """ 
373           Retourne 1 si la valeur est dans l'intervalle permis par
374           l'objet représenté par l'item.
375       """
376       return self.object.isinintervalle(valeur)
377
378   def isvalid(self):
379     valide=self.object.isvalid()
380     return self.object.isvalid()
381
382   #--------------------------------------------------
383   #
384   # Autres ...
385   #
386   #---------------------------------------------------
387   # SetText     a priori inutilisee --> commentee
388   # GetIconName
389   # GetText
390   # getval     a  priori inutilisee --> commentee
391   # set_valeur_co
392   # get_sd_avant_du_bon_type
393   # verif       a  priori inutilisee --> commentee
394   # delete_valeur_co
395
396   #def SetText(self, text):
397   #  try:
398   #    value = eval(text)
399   #    self.object.setval(value)
400   #  except:
401   #    pass
402
403   def GetIconName(self):
404     if self.isvalid():
405       return "ast-green-ball"
406     elif self.object.isoblig():
407       return "ast-red-ball"
408     else:
409       return "ast-yel-ball"
410
411   def GetText(self):
412     """
413     Classe SIMPTreeItem
414     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
415     pointé par self 
416     """
417     text= self.object.GetText()
418     return text
419     
420   #def getval(self):
421   #    return self.object.getval()
422
423   def set_valeur_co(self,nom_co):
424       """
425       Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
426       """
427       return self.object.set_valeur_co(nom_co)
428       
429   def get_sd_avant_du_bon_type(self):
430       """
431       Retourne la liste des noms des SD présentes avant l'étape qui contient
432       le MCS pointé par self et du type requis par ce MCS
433       """
434       a=self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type)
435       return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
436                                                                self.object.definition.type)
437
438   #def verif(self):
439   #    pass
440
441   def delete_valeur_co(self,valeur=None):
442       """
443            Supprime la valeur du mot cle (de type CO)
444            il faut propager la destruction aux autres etapes
445       """
446       if not valeur : valeur=self.object.valeur
447       # XXX faut il vraiment appeler del_sdprod ???
448       #self.object.etape.parent.del_sdprod(valeur)
449       self.object.etape.parent.delete_concept(valeur)
450
451   #-----------------------------------------------
452   #
453   # Methodes liees au type de l objet attendu
454   #
455   #-----------------------------------------------
456   # wait_co 
457   # wait_geom
458   # wait_complex
459   # wait_reel
460   # wait_shell
461   # wait_assd
462   # GetType
463
464   def wait_co(self):
465       """
466       Méthode booléenne qui retourne 1 si l'objet pointé par self
467       attend un objet de type ASSD qui n'existe pas encore (type CO()),
468       0 sinon
469       """
470       return self.object.wait_co()
471
472   def wait_geom(self):
473       """
474       Méthode booléenne qui retourne 1 si l'objet pointé par self
475       attend un objet GEOM, 0 sinon
476       """
477       return self.object.wait_geom()
478     
479   def wait_complex(self):
480       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
481       attend un complexe, 0 sinon """
482       if 'C' in self.object.definition.type:
483           return 1
484       else:
485           return 0
486
487   def wait_reel(self):
488       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
489       attend un réel, 0 sinon """
490       if 'R' in self.object.definition.type:
491           return 1
492       else:
493           return 0
494         
495   def wait_shell(self):
496       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
497       attend un shell, 0 sinon """
498       if 'shell' in self.object.definition.type:
499           return 1
500       else:
501           return 0
502
503   def wait_assd(self):
504       """Méthode booléenne qui retourne 1 si l'objet pointé par self
505       attend un objet de type ASSD ou dérivé, 0 sinon """
506       return self.object.wait_assd()
507     
508   def GetType(self):
509       """ 
510           Retourne le type de valeur attendu par l'objet représenté par l'item.
511       """
512       return self.object.get_type()
513
514   #-----------------------------------------------------
515   #
516   # Methodes liees  a l evaluation de la valeur saisie
517   #
518   #-----------------------------------------------------
519   # eval_valeur
520   # eval_valeur_item
521   # is_CO
522   # traite_reel
523
524   def eval_valeur(self,valeur):
525       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
526       de l'objet pointé par self :
527         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
528         - retourne 'valeur' (chaîne de caractères) sinon
529         - retourne None en cas d invalidite
530         - retourne invalide si 1 des objets du tuple l est
531       """
532       validite=1
533       if type(valeur) in (types.ListType,types.TupleType) :
534          valeurretour=[]
535          for item in valeur :
536              newvaleur,validiteitem=self.eval_valeur_item(item)
537              valeurretour.append(newvaleur)
538              if validiteitem == 0:
539                 validite=0
540       else :
541          valeurretour,validite= self.eval_valeur_item(valeur)
542       if validite == 0 :
543          valeurretour = None
544       return valeurretour,validite
545
546   def eval_valeur_item(self,valeur):
547       """ Lance l'interprétation de 'valeur' qui doit ne pas etre un tuple 
548           - va retourner la valeur de retour et la validite
549             selon le type de l objet attendu
550           - traite les reels et les parametres 
551       """ 
552       if valeur==None or valeur == "" :
553          return None,0
554       validite=1
555       if self.wait_reel():
556              valeurinter = self.traite_reel(valeur)
557              valeurretour,validite= self.object.eval_valeur(valeurinter)
558       elif self.wait_geom():
559              valeurretour,validite = valeur,1
560       else :
561              valeurretour,validite= self.object.eval_valeur(valeur)
562       if validite == 0:
563          if type(valeur) == types.StringType and self.object.wait_TXM():
564             essai_valeur="'" + valeur + "'"
565             valeurretour,validite= self.object.eval_valeur(essai_valeur)
566       if hasattr(valeurretour,'__class__'):
567          #if valeurretour.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
568          if valeurretour.__class__.__name__ in ('PARAMETRE',):
569             validite=1
570       if self.wait_co():
571          try:
572             valeurretour=Accas.CO(valeur)
573          except:
574             valeurretour=None
575             validite=0
576       # on est dans le cas où on a évalué et où on n'aurait pas du
577       if self.object.wait_TXM() :
578           if type(valeurretour) != types.StringType:
579              valeurretour=str(valeur)
580              validite=1
581       return valeurretour,validite
582       
583   def is_CO(self,valeur=None):
584       """
585          Indique si valeur est un concept produit de la macro
586          Cette méthode n'a de sens que pour un MCSIMP d'une MACRO
587          Si valeur vaut None on teste la valeur du mot cle
588       """
589       # Pour savoir si un concept est un nouveau concept de macro
590       # on regarde s'il est présent dans l'attribut sdprods de l'étape
591       # ou si son nom de classe est CO.
592       # Il faut faire les 2 tests car une macro non valide peut etre
593       # dans un etat pas tres catholique avec des CO pas encore types
594       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
595       if not valeur:valeur=self.object.valeur
596       if valeur in self.object.etape.sdprods:return 1
597       if type(valeur) is not types.InstanceType:return 0
598       if valeur.__class__.__name__ == 'CO':return 1
599       return 0
600
601   def is_param(self,valeur) :
602       for param in self.jdc.params:
603           if (repr(param) == valeur):
604              return 1
605       return 0
606
607   def traite_reel(self,valeur):
608       """
609       Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
610       ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
611       ou un EVAL ...
612       """
613       valeur = string.strip(valeur)
614       liste_reels = self.get_sd_avant_du_bon_type()
615       if valeur in liste_reels:
616           return valeur
617       if len(valeur) >= 3 :
618           if valeur[0:4] == 'EVAL' :
619               # on a trouvé un EVAL --> on retourne directement la valeur
620               return valeur
621       if string.find(valeur,'.') == -1 :
622           # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
623           if (self.is_param(valeur)):
624               return valeur
625           else:
626               if string.find(valeur,'e') != -1:
627                  # Notation scientifique ?
628                  try :
629                     r=eval(valeur)
630                     return valeur
631                  except :
632                     return None
633               else :
634                  return valeur+'.'
635       else:
636           return valeur
637         
638
639 import Accas
640 treeitem = SIMPTreeItem
641 objet = Accas.MCSIMP
642