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