]> SALOME platform Git repositories - tools/eficas.git/blob - Ihm/I_MCSIMP.py
Salome HOME
f85d97a5c88654a5116330af645755fae8aea9b0
[tools/eficas.git] / Ihm / I_MCSIMP.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 import types,string
21 import traceback
22 from copy import copy
23 from repr import Repr
24 myrepr = Repr()
25 myrepr.maxstring = 100
26 myrepr.maxother = 100
27
28 from Noyau.N_utils import repr_float
29
30 # Attention : les classes ASSD,.... peuvent etre surchargées
31 # dans le package Accas. Il faut donc prendre des précautions si
32 # on utilise les classes du Noyau pour faire des tests (isxxxx, ...)
33 # Si on veut créer des objets comme des CO avec les classes du noyau
34 # ils n'auront pas les conportements des autres packages (pb!!!)
35 # Il vaut mieux les importer d'Accas mais problème d'import circulaire,
36 # on ne peut pas les importer au début.
37 # On fait donc un import local quand c'est nécessaire (peut occasionner
38 # des pbs de prformance).
39 from Noyau.N_ASSD import ASSD,assd
40 from Noyau.N_GEOM import GEOM,geom
41 from Noyau.N_CO import CO
42 # fin attention
43
44 from Extensions import parametre
45 import I_OBJECT
46
47 class MCSIMP(I_OBJECT.OBJECT):
48   def GetText(self):
49     """
50         Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
51         pointé par self
52     """
53     if self.valeur == None : 
54       return None
55     elif type(self.valeur) == types.FloatType : 
56       #txt = repr_float(self.valeur)
57       # Normalement str fait un travail correct
58       txt = str(self.valeur)
59     elif type(self.valeur) in (types.ListType,types.TupleType) :
60       txt='('
61       i=0
62       for val in self.valeur:
63         if type(val) == types.FloatType : 
64            # Normalement str fait un travail correct
65            #txt=txt + i*',' + repr_float(val)
66            txt=txt + i*',' + str(val)
67         elif type(val) == types.InstanceType and isinstance(val,ASSD): 
68            txt = txt + i*',' + val.get_name()
69     #PN
70     # ajout du elif
71         elif val.__class__.__name__ in  ('PARAMETRE','PARAMETRE_EVAL'):
72              txt = txt + i*','+ str(val) 
73         else: 
74            txt = txt + i*','+ myrepr.repr(val)
75         i=1
76       txt=txt+')'
77     else:
78       txt = self.getval()
79     if type(txt) != types.StringType:
80       if type(txt) == types.InstanceType:
81         if isinstance(txt,parametre.PARAMETRE):
82           return str(txt)
83       return repr(txt)
84     # txt peut etre une longue chaine sur plusieurs lignes.
85     # Il est possible de tronquer cette chaine au premier \n et 
86     # de limiter la longueur de la chaine a 30 caracteres. Cependant
87     # ceci provoque une perte d'information pour l'utilisateur
88     # Pour le moment on retourne la chaine telle que
89     return txt
90
91     # Partie de code inaccessible (pour memoire)
92     # txt est tronquee au dela d'un certain nombre de caractères
93     # et avant tout retour chariot (txt peut etre une chaine de caractères
94     # sur plusieurs lignes (ex:shell)
95     txt = string.split(txt,'\n')[0]
96     if len(txt) < 30 :
97       return txt
98     else:
99       return txt[0:29]
100
101   def getval(self):
102     """ 
103        Retourne une chaîne de caractère représentant la valeur de self 
104     """
105     val=self.valeur
106     if type(val) != types.TupleType :
107       try:
108         return val.get_name()
109       except:
110         return val
111     else :
112       s='( '
113       for item in val :
114         try :
115           s=s+item.get_name()+','
116         except:
117           s=s+`item`+','
118       s=s+' )'
119       return s
120
121   def wait_co(self):
122     """
123         Méthode booléenne qui retourne 1 si l'objet attend un objet ASSD 
124         qui n'existe pas encore (type CO()), 0 sinon
125     """
126     for typ in self.definition.type:
127       if type(typ) == types.ClassType :
128         if issubclass(typ,CO) :
129            return 1
130     return 0
131
132   def wait_assd(self):
133     """ 
134         Méthode booléenne qui retourne 1 si le MCS attend un objet de type ASSD 
135         ou dérivé, 0 sinon
136     """
137     for typ in self.definition.type:
138       if type(typ) == types.ClassType :
139         if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
140           return 1
141     return 0
142
143   def wait_assd_or_geom(self):
144     """ 
145          Retourne 1 si le mot-clé simple attend un objet de type
146          assd, ASSD, geom ou GEOM
147          Retourne 0 dans le cas contraire
148     """
149     for typ in self.definition.type:
150       if type(typ) == types.ClassType :
151         if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
152           return 1
153     return 0
154
155   def wait_geom(self):
156     """ 
157          Retourne 1 si le mot-clé simple attend un objet de type GEOM
158          Retourne 0 dans le cas contraire
159     """
160     for typ in self.definition.type:
161       if type(typ) == types.ClassType :
162         if issubclass(typ,GEOM) : return 1
163     return 0
164
165   def wait_TXM(self):
166     """ 
167          Retourne 1 si le mot-clé simple attend un objet de type TXM
168          Retourne 0 dans le cas contraire
169     """
170     for typ in self.definition.type:
171       if typ == 'TXM' :return 1
172     return 0
173
174   def get_liste_valeurs(self):
175     """
176     """
177     if self.valeur == None:
178       return []
179     elif type(self.valeur) == types.TupleType:
180       return list(self.valeur)
181     elif type(self.valeur) == types.ListType:
182       return self.valeur
183     else:
184       return [self.valeur]
185
186   def isoblig(self):
187     return self.definition.statut=='o'
188
189 #  def set_valeur(self,new_valeur,evaluation='oui'):
190 #    """
191 #        Remplace la valeur de self(si elle existe) par new_valeur
192 #            - si evaluation = 'oui' : 
193 #                        essaie d'évaluer new_valeur dans le contexte
194 #            - si evaluation = 'non' : 
195 #                        n'essaie pas d'évaluer (on stocke une string ou 
196 #                        une valeur de la liste into )
197 #    """
198 #    if evaluation == 'oui' and not self.wait_assd_or_geom():
199 #      valeur,test = self.eval_valeur(new_valeur)
200 #      if test :
201 #        self.val = new_valeur
202 #        self.valeur = valeur
203 #        self.init_modif()
204 #        self.fin_modif()
205 #        return 1
206 #      else:
207 #        # On n'a pas trouve de concept ni réussi à évaluer la valeur 
208 #        # dans le contexte
209 #        # Si le mot cle simple attend un type CO on crée un objet de ce 
210 #        # type de nom new_valeur
211 #        if self.wait_co():
212 #          try:
213 #            # Pour avoir la classe CO avec tous ses comportements
214 #            from Accas import CO
215 #            self.valeur=CO(new_valeur)
216 #          except:
217 #            traceback.print_exc()
218 #            return 0
219 #          self.init_modif()
220 #          self.val=self.valeur
221 #          self.fin_modif()
222 #          return 1
223 #        elif type(new_valeur)==types.StringType and self.wait_TXM():
224 #          self.init_modif()
225 #          self.val = new_valeur
226 #          self.valeur = new_valeur
227 #          self.fin_modif()
228 #          return 1
229 #        else:
230 #          return 0
231 #    else :
232       # on ne fait aucune vérification ...
233   def set_valeur(self,new_valeur,evaluation='oui'):
234         self.init_modif()
235         self.valeur = new_valeur
236         self.val = new_valeur
237         self.fin_modif()
238         return 1
239
240   def eval_valeur(self,new_valeur):
241     """
242         Essaie d'évaluer new_valeur comme une SD, une déclaration Python 
243         ou un EVAL: Retourne la valeur évaluée (ou None) et le test de réussite (1 ou 0)
244     """
245     sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
246     if sd :
247       return sd,1
248     else:
249       d={}
250       # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
251       from Accas import EVAL
252       d['EVAL']=EVAL
253       try :
254         objet = eval(new_valeur,d)
255         return objet,1
256       except Exception:
257         if CONTEXT.debug : traceback.print_exc()
258         return None,0
259
260   def delete_concept(self,sd):
261     """ 
262         Inputs :
263            - sd=concept detruit
264         Fonction :
265         Met a jour la valeur du mot cle simple suite à la disparition 
266         du concept sd
267     """
268     if type(self.valeur) == types.TupleType :
269       if sd in self.valeur:
270         self.valeur=list(self.valeur)
271         self.valeur.remove(sd)
272         self.init_modif()
273     elif type(self.valeur) == types.ListType:
274       if sd in self.valeur:
275         self.valeur.remove(sd)
276         self.init_modif()
277     else:
278       if self.valeur == sd:
279         self.valeur=None
280         self.val=None
281         self.init_modif()
282
283   def replace_concept(self,old_sd,sd):
284     """
285         Inputs :
286            - old_sd=concept remplacé
287            - sd=nouveau concept
288         Fonction :
289         Met a jour la valeur du mot cle simple suite au remplacement 
290         du concept old_sd
291     """
292     if type(self.valeur) == types.TupleType :
293       if old_sd in self.valeur:
294         self.valeur=list(self.valeur)
295         i=self.valeur.index(old_sd)
296         self.valeur[i]=sd
297         self.init_modif()
298     elif type(self.valeur) == types.ListType:
299       if old_sd in self.valeur:
300         i=self.valeur.index(old_sd)
301         self.valeur[i]=sd
302         self.init_modif()
303     else:
304       if self.valeur == old_sd:
305         self.valeur=sd
306         self.val=sd
307         self.init_modif()
308
309   def copy(self):
310     """ Retourne une copie de self """
311     objet = self.makeobjet()
312     # il faut copier les listes et les tuples mais pas les autres valeurs
313     # possibles (réel,SD,...)
314     if type(self.valeur) in (types.ListType,types.TupleType):
315        objet.valeur = copy(self.valeur)
316     else:
317        objet.valeur = self.valeur
318     objet.val = objet.valeur
319     return objet
320
321   def makeobjet(self):
322     return self.definition(val = None, nom = self.nom,parent = self.parent)
323
324   def get_sd_utilisees(self):
325     """ 
326         Retourne une liste qui contient la SD utilisée par self si c'est le cas
327         ou alors une liste vide
328     """
329     l=[]
330     if type(self.valeur) == types.InstanceType:
331       #XXX Est ce différent de isinstance(self.valeur,ASSD) ??
332       if issubclass(self.valeur.__class__,ASSD) : l.append(self.valeur)
333     return l
334
335
336   def set_valeur_co(self,nom_co):
337       """
338           Affecte à self l'objet de type CO et de nom nom_co
339       """
340       step=self.etape.parent
341       if nom_co == None or nom_co == '':
342          new_objet=None
343       else:
344          # Pour le moment on importe en local le CO de Accas.
345          # Si problème de perfs, il faudra faire autrement
346          from Accas import CO
347          # Avant de créer un concept il faut s'assurer du contexte : step 
348          # courant
349          sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
350          if sd:
351             # Si un concept du meme nom existe deja dans la portée de l'étape
352             # on ne crée pas le concept
353             return 0,"un concept de meme nom existe deja"
354          # Il n'existe pas de concept de meme nom. On peut donc le créer 
355          # Il faut néanmoins que la méthode NommerSdProd de step gère les 
356          # contextes en mode editeur
357          # Normalement la méthode  du Noyau doit etre surchargée
358          # On déclare l'étape du mot clé comme etape courante pour NommerSdprod
359          cs= CONTEXT.get_current_step()
360          CONTEXT.unset_current_step()
361          CONTEXT.set_current_step(step)
362          step.set_etape_context(self.etape)
363          new_objet = CO(nom_co)
364          CONTEXT.unset_current_step()
365          CONTEXT.set_current_step(cs)
366       self.init_modif()
367       self.valeur = new_objet
368       self.val = new_objet
369       self.fin_modif()
370       step.reset_context()
371       # On force l'enregistrement de new_objet en tant que concept produit 
372       # de la macro en appelant get_type_produit avec force=1
373       self.etape.get_type_produit(force=1)
374       return 1,"Concept créé"
375         
376   def reparent(self,parent):
377      """
378          Cette methode sert a reinitialiser la parente de l'objet
379      """
380      self.parent=parent
381      self.jdc=parent.jdc
382      self.etape=parent.etape
383
384   def verif_existence_sd(self):
385      """
386         Vérifie que les structures de données utilisées dans self existent bien dans le contexte
387         avant étape, sinon enlève la référence à ces concepts
388      """
389      l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()  
390      if type(self.valeur) in (types.TupleType,types.ListType) :
391        l=[]
392        for sd in self.valeur:
393          if isinstance(sd,ASSD) :
394             if sd in l_sd_avant_etape :
395                l.append(sd)
396          else:
397             l.append(sd)
398        self.valeur=l
399        # Est ce init_modif ou init_modif_up
400        # Normalement init_modif va avec fin_modif
401        self.init_modif()
402        self.fin_modif()
403      else:
404        if isinstance(self.valeur,ASSD) :
405           if self.valeur not in l_sd_avant_etape :
406              self.valeur = None
407              self.init_modif()
408              self.fin_modif()
409  
410   def get_min_max(self):
411      """
412      Retourne les valeurs min et max admissibles pour la valeur de self
413      """
414      return self.definition.min,self.definition.max
415
416
417   def get_type(self):
418      """
419      Retourne le type attendu par le mot-clé simple
420      """
421      return self.definition.type
422  
423 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
424 # Elles doivent etre reintegrees des que possible
425
426   def is_complexe(self,valeur):
427       """ Retourne 1 si valeur est un complexe, 0 sinon """
428       if type(valeur) == types.InstanceType :
429         #XXX je n'y touche pas pour ne pas tout casser mais il serait
430         #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
431         if valeur.__class__.__name__ in ('EVAL','complexe','PARAMETRE_EVAL'):
432           return 1
433         elif valeur.__class__.__name__ in ('PARAMETRE',):
434           # il faut tester si la valeur du parametre est un entier
435           #XXX ne serait ce pas plutot complexe ???? sinon expliquer
436           return self.is_entier(valeur.valeur)
437         else:
438           print "Objet non reconnu dans is_complexe %s" %`valeur`
439           return 0
440       # Pour permettre l'utilisation de complexes Python
441       #elif type(valeur) == types.ComplexType:
442         #return 1
443       elif type(valeur) != types.TupleType :
444         return 0
445       else:
446         if len(valeur) != 3 :
447           return 0
448         else:
449           if type(valeur[0]) != types.StringType : return 0
450           if string.strip(valeur[0]) not in ('RI','MP'):
451             return 0
452           else:
453             if not self.is_reel(valeur[1]) or not self.is_reel(valeur[2]) : return 0
454             else: return 1
455
456   def is_reel(self,valeur):
457       """
458       Retourne 1 si valeur est un reel, 0 sinon
459       """
460       if type(valeur) == types.InstanceType :
461         #XXX je n'y touche pas pour ne pas tout casser mais il serait
462         #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('R'), par exemple
463         #XXX ou valeur.is_reel()
464         #XXX ou encore valeur.compare(self.is_reel)
465         if valeur.__class__.__name__ in ('EVAL','reel','PARAMETRE_EVAL') :
466           return 1
467         elif valeur.__class__.__name__ in ('PARAMETRE',):
468           # il faut tester si la valeur du parametre est un réel
469           return self.is_reel(valeur.valeur)
470         else:
471           print "Objet non reconnu dans is_reel %s" %`valeur`
472           return 0
473       elif type(valeur) not in (types.IntType,types.FloatType,types.LongType):
474         # ce n'est pas un réel
475         return 0
476       else:
477         return 1
478
479   def is_entier(self,valeur):
480       """ Retourne 1 si valeur est un entier, 0 sinon """
481       if type(valeur) == types.InstanceType :
482         #XXX je n'y touche pas pour ne pas tout casser mais il serait
483         #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
484         if valeur.__class__.__name__ in ('EVAL','entier','PARAMETRE_EVAL') :
485           return 1
486         elif valeur.__class__.__name__ in ('PARAMETRE',):
487           # il faut tester si la valeur du parametre est un entier
488           return self.is_entier(valeur.valeur)
489         else:
490           print "Objet non reconnu dans is_reel %s" %`valeur`
491           return 0
492       elif type(valeur) not in (types.IntType,types.LongType):
493         # ce n'est pas un entier
494         return 0
495       else:
496         return 1
497
498   def is_object_from(self,objet,classe):
499       """
500            Retourne 1 si valeur est un objet de la classe classe ou d'une 
501            sous-classe de classe, 0 sinon
502       """
503       if type(objet) != types.InstanceType :
504           return 0
505       if not objet.__class__ == classe and not issubclass(objet.__class__,classe):
506         return 0
507       else:
508         return 1
509
510   def get_valid(self):
511        if hasattr(self,'valid'):
512           return self.valid
513        else:
514           self.valid=None
515           return None
516
517   def set_valid(self,valid):
518        old_valid=self.get_valid()
519        self.valid = valid
520        self.state = 'unchanged'
521        if not old_valid or old_valid != self.valid :
522            self.init_modif_up()
523
524   def isvalid(self,cr='non'):
525       """
526          Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
527
528            - 0 si l'objet est invalide
529            - 1 si l'objet est valide
530
531          Le paramètre cr permet de paramétrer le traitement. Si cr == 'oui'
532          la méthode construit également un comte-rendu de validation
533          dans self.cr qui doit avoir été créé préalablement.
534       """
535       if self.state == 'unchanged':
536         return self.valid
537       else:
538         v=self.valeur
539         valid = 1
540         #  verifiaction presence
541         if self.isoblig() and v == None :
542           if cr == 'oui' :
543             self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
544           valid = 0
545
546         if v is None:
547           valid=0
548           if cr == 'oui' :
549              self.cr.fatal("None n'est pas une valeur autorisée")
550         else:
551           # type,into ...
552           valid = self.verif_type(val=v,cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
553           #
554           # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
555           #
556           if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
557             if cr == 'oui' :
558               self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
559             valid=0
560           # fin des validateurs
561           #
562
563         self.set_valid(valid)
564         return self.valid
565