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