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