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