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