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