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.
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.
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.
20 # ======================================================================
26 myrepr.maxstring = 100
29 from Noyau.N_utils import repr_float
33 # Attention : les classes ASSD,.... peuvent etre surchargées
34 # dans le package Accas. Il faut donc prendre des précautions si
35 # on utilise les classes du Noyau pour faire des tests (isxxxx, ...)
36 # Si on veut créer des objets comme des CO avec les classes du noyau
37 # ils n'auront pas les conportements des autres packages (pb!!!)
38 # Il vaut mieux les importer d'Accas mais problème d'import circulaire,
39 # on ne peut pas les importer au début.
40 # On fait donc un import local quand c'est nécessaire (peut occasionner
41 # des pbs de prformance).
42 from Noyau.N_ASSD import ASSD,assd
43 from Noyau.N_GEOM import GEOM,geom
44 from Noyau.N_CO import CO
48 from Extensions import parametre
49 from Extensions import param2
52 from I_VALIDATOR import ValError,listProto
54 class MCSIMP(I_OBJECT.OBJECT):
57 def isvalid(self,cr='non'):
58 if self.state == 'unchanged':
60 for type_permis in self.definition.type:
61 if hasattr(type_permis, "__class__") and type_permis.__class__.__name__ == 'Matrice':
62 self.monType=type_permis
63 return self.valideMatrice(cr=cr)
64 return Validation.V_MCSIMP.MCSIMP.isvalid(self,cr=cr)
66 def GetNomConcept(self):
70 nomconcept=p.get_sdname()
74 nomconcept= p.object.get_sdname()
83 Retourne le texte a afficher dans l'arbre représentant la valeur de l'objet
87 if self.valeur == None :
89 elif type(self.valeur) == types.FloatType :
90 # Traitement d'un flottant isolé
91 txt = str(self.valeur)
92 clefobj=self.GetNomConcept()
93 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
94 if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(self.valeur):
95 txt=self.jdc.appli.appliEficas.dict_reels[clefobj][self.valeur]
96 elif type(self.valeur) in (types.ListType,types.TupleType) :
97 # Traitement des listes
100 for val in self.valeur:
101 if type(val) == types.FloatType :
102 clefobj=self.GetNomConcept()
103 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
104 if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(val):
105 txt=txt + sep +self.jdc.appli.appliEficas.dict_reels[clefobj][val]
107 txt=txt + sep + str(val)
109 txt=txt + sep + str(val)
111 txt = txt + sep+ str(val)
113 #ligne trop longue, on tronque
119 # Traitement des autres cas
120 txt = str(self.valeur)
122 # txt peut etre une longue chaine sur plusieurs lignes.
123 # Il est possible de tronquer cette chaine au premier \n et
124 # de limiter la longueur de la chaine a 30 caracteres. Cependant
125 # ceci provoque une perte d'information pour l'utilisateur
126 # Pour le moment on retourne la chaine telle que
131 Retourne une chaîne de caractère représentant la valeur de self
134 if type(val) == types.FloatType :
135 clefobj=self.GetNomConcept()
136 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
137 if self.jdc.appli.appliEficas.appliEficas.dict_reels[clefobj].has_key(val):
138 return self.jdc.appli.appliEficas.dict_reels[clefobj][val]
139 if type(val) != types.TupleType :
141 return val.get_name()
148 s=s+item.get_name()+','
156 Méthode booléenne qui retourne 1 si l'objet attend un objet ASSD
157 qui n'existe pas encore (type CO()), 0 sinon
159 for typ in self.definition.type:
160 if type(typ) == types.ClassType or isinstance(typ,type):
161 if issubclass(typ,CO) :
167 Méthode booléenne qui retourne 1 si le MCS attend un objet de type ASSD
170 for typ in self.definition.type:
171 if type(typ) == types.ClassType or isinstance(typ,type):
172 if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
176 def wait_assd_or_geom(self):
178 Retourne 1 si le mot-clé simple attend un objet de type
179 assd, ASSD, geom ou GEOM
180 Retourne 0 dans le cas contraire
182 for typ in self.definition.type:
183 if type(typ) == types.ClassType or isinstance(typ,type):
184 if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
190 Retourne 1 si le mot-clé simple attend un objet de type GEOM
191 Retourne 0 dans le cas contraire
193 for typ in self.definition.type:
194 if type(typ) == types.ClassType or isinstance(typ,type):
195 if issubclass(typ,GEOM) : return 1
200 Retourne 1 si le mot-clé simple attend un objet de type TXM
201 Retourne 0 dans le cas contraire
203 for typ in self.definition.type:
204 if typ == 'TXM' :return 1
207 def get_liste_valeurs(self):
210 if self.valeur == None:
212 elif type(self.valeur) == types.TupleType:
213 return list(self.valeur)
214 elif type(self.valeur) == types.ListType:
220 return self.definition.statut=='o'
222 def valid_val(self,valeur):
224 Verifie que la valeur passee en argument (valeur) est valide
225 sans modifier la valeur courante
227 lval=listProto.adapt(valeur)
230 mess="None n'est pas une valeur autorisée"
234 self.typeProto.adapt(val)
235 self.intoProto.adapt(val)
236 self.cardProto.adapt(lval)
237 if self.definition.validators:
238 self.definition.validators.convert(lval)
245 def valid_valeur(self,new_valeur):
247 Verifie que la valeur passee en argument (new_valeur) est valide
248 sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
250 validite,mess=self.valid_val(new_valeur)
253 def valid_valeur_partielle(self,new_valeur):
255 Verifie que la valeur passee en argument (new_valeur) est une liste partiellement valide
256 sans modifier la valeur courante du mot cle
260 for val in new_valeur:
261 self.typeProto.adapt(val)
262 self.intoProto.adapt(val)
263 #on ne verifie pas la cardinalité
264 if self.definition.validators:
265 validite=self.definition.validators.valide_liste_partielle(new_valeur)
271 def update_condition_bloc(self):
272 """ Met a jour les blocs conditionnels dependant du mot cle simple self
274 if self.definition.position == 'global' :
275 self.etape.deep_update_condition_bloc()
276 elif self.definition.position == 'global_jdc' :
277 self.jdc.deep_update_condition_bloc()
279 self.parent.update_condition_bloc()
281 def set_valeur(self,new_valeur,evaluation='oui'):
282 #print "set_valeur",new_valeur
284 self.valeur = new_valeur
285 self.val = new_valeur
286 self.update_condition_bloc()
287 self.etape.modified()
291 def eval_valeur(self,new_valeur):
293 Essaie d'évaluer new_valeur comme une SD, une déclaration Python
294 ou un EVAL: Retourne la valeur évaluée (ou None) et le test de réussite (1 ou 0)
296 sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
297 #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
301 lsd = self.jdc.cherche_list_avant(self.etape,new_valeur)
306 # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
309 objet = eval(new_valeur,d)
312 itparam=self.cherche_item_parametre(new_valeur)
316 object=eval(new_valeur.valeur,d)
319 if CONTEXT.debug : traceback.print_exc()
322 def eval_val(self,new_valeur):
324 Tente d'evaluer new_valeur comme un objet du jdc (par appel a eval_val_item)
325 ou comme une liste de ces memes objets
326 Si new_valeur contient au moins un separateur (,), tente l'evaluation sur
329 if type(new_valeur) in (types.ListType,types.TupleType):
331 for item in new_valeur :
332 valeurretour.append(self.eval_val_item(item))
335 valeur=self.eval_val_item(new_valeur)
338 def eval_val_item(self,new_valeur):
340 Tente d'evaluer new_valeur comme un concept, un parametre, un objet Python
341 Si c'est impossible retourne new_valeur inchange
342 argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
344 if self.etape and self.etape.parent:
345 valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
352 #traceback.print_exc()
356 def cherche_item_parametre (self,new_valeur):
358 nomparam=new_valeur[0:new_valeur.find("[")]
359 indice=new_valeur[new_valeur.find("[")+1:new_valeur.find("]")]
360 for p in self.jdc.params:
361 if p.nom == nomparam :
362 if int(indice) < len(p.get_valeurs()):
363 itparam=parametre.ITEM_PARAMETRE(p,int(indice))
369 def update_concept(self,sd):
370 if type(self.valeur) in (types.ListType,types.TupleType) :
371 if sd in self.valeur:
375 if sd == self.valeur:
379 def delete_concept(self,sd):
384 Met a jour la valeur du mot cle simple suite a la disparition
386 Attention aux matrices
388 if type(self.valeur) == types.TupleType :
389 if sd in self.valeur:
391 self.valeur=list(self.valeur)
392 self.valeur.remove(sd)
394 elif type(self.valeur) == types.ListType:
395 if sd in self.valeur:
397 self.valeur.remove(sd)
400 if self.valeur == sd:
405 # Glut Horrible pour les matrices ???
406 if sd.__class__.__name__== "variable":
407 for type_permis in self.definition.type:
408 if type(type_permis) == types.InstanceType:
409 if type_permis.__class__.__name__ == 'Matrice' :
414 def replace_concept(self,old_sd,sd):
417 - old_sd=concept remplacé
420 Met a jour la valeur du mot cle simple suite au remplacement
423 #print "replace_concept",old_sd,sd
424 if type(self.valeur) == types.TupleType :
425 if old_sd in self.valeur:
427 self.valeur=list(self.valeur)
428 i=self.valeur.index(old_sd)
431 elif type(self.valeur) == types.ListType:
432 if old_sd in self.valeur:
434 i=self.valeur.index(old_sd)
438 if self.valeur == old_sd:
444 def set_valeur_co(self,nom_co):
446 Affecte a self l'objet de type CO et de nom nom_co
448 #print "set_valeur_co",nom_co
449 step=self.etape.parent
450 if nom_co == None or nom_co == '':
453 # Avant de créer un concept il faut s'assurer du contexte : step
455 sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
457 # Si un concept du meme nom existe deja dans la portée de l'étape
458 # on ne crée pas le concept
459 return 0,"un concept de meme nom existe deja"
460 # Il n'existe pas de concept de meme nom. On peut donc le créer
461 # Il faut néanmoins que la méthode NommerSdProd de step gère les
462 # contextes en mode editeur
463 # Normalement la méthode du Noyau doit etre surchargée
464 # On déclare l'étape du mot clé comme etape courante pour NommerSdprod
465 cs= CONTEXT.get_current_step()
466 CONTEXT.unset_current_step()
467 CONTEXT.set_current_step(step)
468 step.set_etape_context(self.etape)
469 new_objet = Accas.CO(nom_co)
470 CONTEXT.unset_current_step()
471 CONTEXT.set_current_step(cs)
473 self.valeur = new_objet
475 # On force l'enregistrement de new_objet en tant que concept produit
476 # de la macro en appelant get_type_produit avec force=1
477 self.etape.get_type_produit(force=1)
480 #print "set_valeur_co",new_objet
481 return 1,"Concept créé"
483 def verif_existence_sd(self):
485 Vérifie que les structures de données utilisées dans self existent bien dans le contexte
486 avant étape, sinon enlève la référea ces concepts
488 #print "verif_existence_sd"
489 # Attention : possible probleme avec include
490 # A priori il n'y a pas de raison de retirer les concepts non existants
491 # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
492 l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()
493 if type(self.valeur) in (types.TupleType,types.ListType) :
495 for sd in self.valeur:
496 if isinstance(sd,ASSD) :
497 if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
501 if len(l) < len(self.valeur):
506 if isinstance(self.valeur,ASSD) :
507 if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
512 def get_min_max(self):
514 Retourne les valeurs min et max admissibles pour la valeur de self
516 return self.definition.min,self.definition.max
521 Retourne le type attendu par le mot-clé simple
523 return self.definition.type
525 def delete_mc_global(self):
526 """ Retire self des declarations globales
528 if self.definition.position == 'global' :
529 etape = self.get_etape()
531 del etape.mc_globaux[self.nom]
532 elif self.definition.position == 'global_jdc' :
533 del self.jdc.mc_globaux[self.nom]
535 def update_mc_global(self):
537 Met a jour les mots cles globaux enregistrés dans l'étape parente
538 et dans le jdc parent.
539 Un mot cle simple peut etre global.
541 if self.definition.position == 'global' :
542 etape = self.get_etape()
544 etape.mc_globaux[self.nom]=self
545 elif self.definition.position == 'global_jdc' :
547 self.jdc.mc_globaux[self.nom]=self
549 def nbrColonnes(self):
550 genea = self.get_genealogie()
551 if "VALE_C" in genea and "DEFI_FONCTION" in genea : return 3
552 if "VALE" in genea and "DEFI_FONCTION" in genea : return 2
555 def valide_item(self,item):
556 """Valide un item isolé. Cet item est candidata l'ajout a la liste existante"""
560 self.typeProto.adapt(item)
561 #on verifie les choix possibles
562 self.intoProto.adapt(item)
563 #on ne verifie pas la cardinalité
564 if self.definition.validators:
565 valid=self.definition.validators.verif_item(item)
567 #traceback.print_exc()
571 def verif_type(self,item):
572 """Verifie le type d'un item de liste"""
575 self.typeProto.adapt(item)
576 #on verifie les choix possibles
577 self.intoProto.adapt(item)
578 #on ne verifie pas la cardinalité mais on verifie les validateurs
579 if self.definition.validators:
580 valid=self.definition.validators.verif_item(item)
584 #traceback.print_exc()
589 def valideMatrice(self,cr):
590 #Attention, la matrice contient comme dernier tuple l ordre des variables
591 if self.monType.methodeCalculTaille != None :
592 apply (MCSIMP.__dict__[self.monType.methodeCalculTaille],(self,))
596 if len(self.valeur) == self.monType.nbLigs +1:
598 for i in range(len(self.valeur) -1):
599 if len(self.valeur[i])!= self.monType.nbCols:
608 self.cr.fatal("La matrice n est pas une matrice "+str(self.monType.nbLigs)+","+str(self.monType.nbCols))
612 def NbDeVariables(self):
613 listeVariables=self.jdc.get_variables(self.etape)
614 self.monType.nbLigs=len(listeVariables)
615 self.monType.nbCols=len(listeVariables)
618 #--------------------------------------------------------------------------------
620 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
621 # Elles doivent etre reintegrees des que possible
624 def verif_typeihm(self,val,cr='non'):
629 traceback.print_exc()
631 return self.verif_type(val,cr)
633 def verif_typeliste(self,val,cr='non') :
636 verif=verif+self.verif_typeihm(v,cr)
639 def init_modif_up(self):
640 Validation.V_MCSIMP.MCSIMP.init_modif_up(self)
641 CONNECTOR.Emit(self,"valid")