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