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):
56 def isvalid(self,cr='non'):
57 if self.state == 'unchanged':
59 for type_permis in self.definition.type:
60 if hasattr(type_permis, "__class__") and type_permis.__class__.__name__ == 'Matrice':
61 self.monType=type_permis
62 return self.valideMatrice(cr=cr)
63 return Validation.V_MCSIMP.MCSIMP.isvalid(self,cr=cr)
65 def GetNomConcept(self):
69 nomconcept=p.get_sdname()
73 nomconcept= p.object.get_sdname()
82 Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
86 if self.valeur == None :
88 elif type(self.valeur) == types.FloatType :
89 # Traitement d'un flottant isolé
90 txt = str(self.valeur)
91 clefobj=self.GetNomConcept()
92 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
93 if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(self.valeur):
94 txt=self.jdc.appli.appliEficas.dict_reels[clefobj][self.valeur]
95 elif type(self.valeur) in (types.ListType,types.TupleType) :
96 # Traitement des listes
99 for val in self.valeur:
100 if type(val) == types.FloatType :
101 clefobj=self.GetNomConcept()
102 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
103 if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(val):
104 txt=txt + sep +self.jdc.appli.appliEficas.dict_reels[clefobj][val]
106 txt=txt + sep + str(val)
108 txt=txt + sep + str(val)
110 txt = txt + sep+ str(val)
112 #ligne trop longue, on tronque
118 # Traitement des autres cas
119 txt = str(self.valeur)
121 # txt peut etre une longue chaine sur plusieurs lignes.
122 # Il est possible de tronquer cette chaine au premier \n et
123 # de limiter la longueur de la chaine a 30 caracteres. Cependant
124 # ceci provoque une perte d'information pour l'utilisateur
125 # Pour le moment on retourne la chaine telle que
130 Retourne une chaîne de caractère représentant la valeur de self
133 if type(val) == types.FloatType :
134 clefobj=self.GetNomConcept()
135 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
136 if self.jdc.appli.appliEficas.appliEficas.dict_reels[clefobj].has_key(val):
137 return self.jdc.appli.appliEficas.dict_reels[clefobj][val]
138 if type(val) != types.TupleType :
140 return val.get_name()
147 s=s+item.get_name()+','
155 Méthode booléenne qui retourne 1 si l'objet attend un objet ASSD
156 qui n'existe pas encore (type CO()), 0 sinon
158 for typ in self.definition.type:
159 if type(typ) == types.ClassType or isinstance(typ,type):
160 if issubclass(typ,CO) :
166 Méthode booléenne qui retourne 1 si le MCS attend un objet de type ASSD
169 for typ in self.definition.type:
170 if type(typ) == types.ClassType or isinstance(typ,type):
171 if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
175 def wait_assd_or_geom(self):
177 Retourne 1 si le mot-clé simple attend un objet de type
178 assd, ASSD, geom ou GEOM
179 Retourne 0 dans le cas contraire
181 for typ in self.definition.type:
182 if type(typ) == types.ClassType or isinstance(typ,type):
183 if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
189 Retourne 1 si le mot-clé simple attend un objet de type GEOM
190 Retourne 0 dans le cas contraire
192 for typ in self.definition.type:
193 if type(typ) == types.ClassType or isinstance(typ,type):
194 if issubclass(typ,GEOM) : return 1
199 Retourne 1 si le mot-clé simple attend un objet de type TXM
200 Retourne 0 dans le cas contraire
202 for typ in self.definition.type:
203 if typ == 'TXM' :return 1
206 def get_liste_valeurs(self):
209 if self.valeur == None:
211 elif type(self.valeur) == types.TupleType:
212 return list(self.valeur)
213 elif type(self.valeur) == types.ListType:
219 return self.definition.statut=='o'
221 def valid_val(self,valeur):
223 Verifie que la valeur passee en argument (valeur) est valide
224 sans modifier la valeur courante
226 lval=listProto.adapt(valeur)
229 mess="None n'est pas une valeur autorisée"
233 self.typeProto.adapt(val)
234 self.intoProto.adapt(val)
235 self.cardProto.adapt(lval)
236 if self.definition.validators:
237 self.definition.validators.convert(lval)
244 def valid_valeur(self,new_valeur):
246 Verifie que la valeur passee en argument (new_valeur) est valide
247 sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
249 validite,mess=self.valid_val(new_valeur)
252 def valid_valeur_partielle(self,new_valeur):
254 Verifie que la valeur passee en argument (new_valeur) est une liste partiellement valide
255 sans modifier la valeur courante du mot cle
259 for val in new_valeur:
260 self.typeProto.adapt(val)
261 self.intoProto.adapt(val)
262 #on ne verifie pas la cardinalité
263 if self.definition.validators:
264 validite=self.definition.validators.valide_liste_partielle(new_valeur)
270 def update_condition_bloc(self):
271 """ Met a jour les blocs conditionnels dependant du mot cle simple self
273 if self.definition.position == 'global' :
274 self.etape.deep_update_condition_bloc()
275 elif self.definition.position == 'global_jdc' :
276 self.jdc.deep_update_condition_bloc()
278 self.parent.update_condition_bloc()
280 def set_valeur(self,new_valeur,evaluation='oui'):
281 #print "set_valeur",new_valeur
283 self.valeur = new_valeur
284 self.val = new_valeur
285 self.update_condition_bloc()
286 self.etape.modified()
290 def eval_valeur(self,new_valeur):
292 Essaie d'évaluer new_valeur comme une SD, une déclaration Python
293 ou un EVAL: Retourne la valeur évaluée (ou None) et le test de réussite (1 ou 0)
295 sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
296 #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
300 lsd = self.jdc.cherche_list_avant(self.etape,new_valeur)
305 # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
308 objet = eval(new_valeur,d)
311 itparam=self.cherche_item_parametre(new_valeur)
315 object=eval(new_valeur.valeur,d)
318 if CONTEXT.debug : traceback.print_exc()
321 def eval_val(self,new_valeur):
323 Tente d'evaluer new_valeur comme un objet du jdc (par appel a eval_val_item)
324 ou comme une liste de ces memes objets
325 Si new_valeur contient au moins un separateur (,), tente l'evaluation sur
328 if type(new_valeur) in (types.ListType,types.TupleType):
330 for item in new_valeur :
331 valeurretour.append(self.eval_val_item(item))
334 valeur=self.eval_val_item(new_valeur)
337 def eval_val_item(self,new_valeur):
339 Tente d'evaluer new_valeur comme un concept, un parametre, un objet Python
340 Si c'est impossible retourne new_valeur inchange
341 argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
343 if self.etape and self.etape.parent:
344 valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
351 #traceback.print_exc()
355 def cherche_item_parametre (self,new_valeur):
357 nomparam=new_valeur[0:new_valeur.find("[")]
358 indice=new_valeur[new_valeur.find("[")+1:new_valeur.find("]")]
359 for p in self.jdc.params:
360 if p.nom == nomparam :
361 if int(indice) < len(p.get_valeurs()):
362 itparam=parametre.ITEM_PARAMETRE(p,int(indice))
368 def update_concept(self,sd):
369 if type(self.valeur) in (types.ListType,types.TupleType) :
370 if sd in self.valeur:
374 if sd == self.valeur:
378 def delete_concept(self,sd):
383 Met a jour la valeur du mot cle simple suite à la disparition
385 Attention aux matrices
387 if type(self.valeur) == types.TupleType :
388 if sd in self.valeur:
390 self.valeur=list(self.valeur)
391 self.valeur.remove(sd)
393 elif type(self.valeur) == types.ListType:
394 if sd in self.valeur:
396 self.valeur.remove(sd)
399 if self.valeur == sd:
404 # Glut Horrible pour les matrices ???
405 if sd.__class__.__name__== "variable":
406 for type_permis in self.definition.type:
407 if type(type_permis) == types.InstanceType:
408 if type_permis.__class__.__name__ == 'Matrice' :
413 def replace_concept(self,old_sd,sd):
416 - old_sd=concept remplacé
419 Met a jour la valeur du mot cle simple suite au remplacement
422 #print "replace_concept",old_sd,sd
423 if type(self.valeur) == types.TupleType :
424 if old_sd in self.valeur:
426 self.valeur=list(self.valeur)
427 i=self.valeur.index(old_sd)
430 elif type(self.valeur) == types.ListType:
431 if old_sd in self.valeur:
433 i=self.valeur.index(old_sd)
437 if self.valeur == old_sd:
443 def set_valeur_co(self,nom_co):
445 Affecte à self l'objet de type CO et de nom nom_co
447 #print "set_valeur_co",nom_co
448 step=self.etape.parent
449 if nom_co == None or nom_co == '':
452 # Avant de créer un concept il faut s'assurer du contexte : step
454 sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
456 # Si un concept du meme nom existe deja dans la portée de l'étape
457 # on ne crée pas le concept
458 return 0,"un concept de meme nom existe deja"
459 # Il n'existe pas de concept de meme nom. On peut donc le créer
460 # Il faut néanmoins que la méthode NommerSdProd de step gère les
461 # contextes en mode editeur
462 # Normalement la méthode du Noyau doit etre surchargée
463 # On déclare l'étape du mot clé comme etape courante pour NommerSdprod
464 cs= CONTEXT.get_current_step()
465 CONTEXT.unset_current_step()
466 CONTEXT.set_current_step(step)
467 step.set_etape_context(self.etape)
468 new_objet = Accas.CO(nom_co)
469 CONTEXT.unset_current_step()
470 CONTEXT.set_current_step(cs)
472 self.valeur = new_objet
474 # On force l'enregistrement de new_objet en tant que concept produit
475 # de la macro en appelant get_type_produit avec force=1
476 self.etape.get_type_produit(force=1)
479 #print "set_valeur_co",new_objet
480 return 1,"Concept créé"
482 def verif_existence_sd(self):
484 Vérifie que les structures de données utilisées dans self existent bien dans le contexte
485 avant étape, sinon enlève la référence à ces concepts
487 #print "verif_existence_sd"
488 # Attention : possible probleme avec include
489 # A priori il n'y a pas de raison de retirer les concepts non existants
490 # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
491 l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()
492 if type(self.valeur) in (types.TupleType,types.ListType) :
494 for sd in self.valeur:
495 if isinstance(sd,ASSD) :
496 if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
500 if len(l) < len(self.valeur):
505 if isinstance(self.valeur,ASSD) :
506 if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
511 def get_min_max(self):
513 Retourne les valeurs min et max admissibles pour la valeur de self
515 return self.definition.min,self.definition.max
520 Retourne le type attendu par le mot-clé simple
522 return self.definition.type
524 def delete_mc_global(self):
525 """ Retire self des declarations globales
527 if self.definition.position == 'global' :
528 etape = self.get_etape()
530 del etape.mc_globaux[self.nom]
531 elif self.definition.position == 'global_jdc' :
532 del self.jdc.mc_globaux[self.nom]
534 def update_mc_global(self):
536 Met a jour les mots cles globaux enregistrés dans l'étape parente
537 et dans le jdc parent.
538 Un mot cle simple peut etre global.
540 if self.definition.position == 'global' :
541 etape = self.get_etape()
543 etape.mc_globaux[self.nom]=self
544 elif self.definition.position == 'global_jdc' :
546 self.jdc.mc_globaux[self.nom]=self
548 def nbrColonnes(self):
549 genea = self.get_genealogie()
550 if "VALE_C" in genea and "DEFI_FONCTION" in genea : return 3
551 if "VALE" in genea and "DEFI_FONCTION" in genea : return 2
554 def valide_item(self,item):
555 """Valide un item isolé. Cet item est candidat à l'ajout à la liste existante"""
559 self.typeProto.adapt(item)
560 #on verifie les choix possibles
561 self.intoProto.adapt(item)
562 #on ne verifie pas la cardinalité
563 if self.definition.validators:
564 valid=self.definition.validators.verif_item(item)
566 #traceback.print_exc()
570 def verif_type(self,item):
571 """Verifie le type d'un item de liste"""
574 self.typeProto.adapt(item)
575 #on verifie les choix possibles
576 self.intoProto.adapt(item)
577 #on ne verifie pas la cardinalité mais on verifie les validateurs
578 if self.definition.validators:
579 valid=self.definition.validators.verif_item(item)
583 #traceback.print_exc()
588 def valideMatrice(self,cr):
589 #Attention, la matrice contient comme dernier tuple l ordre des variables
590 if self.monType.methodeCalculTaille != None :
591 apply (MCSIMP.__dict__[self.monType.methodeCalculTaille],(self,))
595 if len(self.valeur) == self.monType.nbLigs +1:
597 for i in range(len(self.valeur) -1):
598 if len(self.valeur[i])!= self.monType.nbCols:
607 self.cr.fatal("La matrice n est pas une matrice "+str(self.monType.nbLigs)+","+str(self.monType.nbCols))
611 def NbDeVariables(self):
612 listeVariables=self.jdc.get_variables(self.etape)
613 self.monType.nbLigs=len(listeVariables)
614 self.monType.nbCols=len(listeVariables)
617 #--------------------------------------------------------------------------------
619 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
620 # Elles doivent etre reintegrees des que possible
623 def verif_typeihm(self,val,cr='non'):
628 traceback.print_exc()
630 return self.verif_type(val,cr)
632 def verif_typeliste(self,val,cr='non') :
635 verif=verif+self.verif_typeihm(v,cr)
638 def init_modif_up(self):
639 Validation.V_MCSIMP.MCSIMP.init_modif_up(self)
640 CONNECTOR.Emit(self,"valid")