1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 from Extensions.i18n import tr
25 from Extensions.eficas_exception import EficasException
27 myrepr.maxstring = 100
30 from Noyau.N_utils import repr_float
34 # Attention : les classes ASSD,.... peuvent etre surchargees
35 # dans le package Accas. Il faut donc prendre des precautions si
36 # on utilise les classes du Noyau pour faire des tests (isxxxx, ...)
37 # Si on veut creer des objets comme des CO avec les classes du noyau
38 # ils n'auront pas les conportements des autres packages (pb!!!)
39 # Il vaut mieux les importer d'Accas mais probleme d'import circulaire,
40 # on ne peut pas les importer au debut.
41 # On fait donc un import local quand c'est necessaire (peut occasionner
42 # des pbs de prformance).
43 from Noyau.N_ASSD import ASSD,assd
44 from Noyau.N_GEOM import GEOM,geom
45 from Noyau.N_CO import CO
49 from Extensions import parametre
50 from Extensions import param2
53 from I_VALIDATOR import ValError,listProto
55 class MCSIMP(I_OBJECT.OBJECT):
58 def isvalid(self,cr='non'):
59 if self.state == 'unchanged':
61 for type_permis in self.definition.type:
62 if hasattr(type_permis, "__class__") and type_permis.__class__.__name__ == 'Matrice':
63 self.monType=type_permis
64 return self.valideMatrice(cr=cr)
65 return Validation.V_MCSIMP.MCSIMP.isvalid(self,cr=cr)
67 def GetNomConcept(self):
71 nomconcept=p.get_sdname()
75 nomconcept= p.object.get_sdname()
84 Retourne le texte a afficher dans l'arbre representant la valeur de l'objet
88 if self.valeur == None :
90 elif type(self.valeur) == types.FloatType :
91 # Traitement d'un flottant isole
92 txt = str(self.valeur)
93 clefobj=self.GetNomConcept()
94 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
95 if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(self.valeur):
96 txt=self.jdc.appli.appliEficas.dict_reels[clefobj][self.valeur]
97 elif type(self.valeur) in (types.ListType,types.TupleType) :
98 # Traitement des listes
101 for val in self.valeur:
102 if type(val) == types.FloatType :
103 clefobj=self.GetNomConcept()
104 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
105 if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(val):
106 txt=txt + sep +self.jdc.appli.appliEficas.dict_reels[clefobj][val]
108 txt=txt + sep + str(val)
110 txt=txt + sep + str(val)
112 txt = txt + sep+ str(val)
114 #ligne trop longue, on tronque
120 # Traitement des autres cas
121 txt = str(self.valeur)
123 # txt peut etre une longue chaine sur plusieurs lignes.
124 # Il est possible de tronquer cette chaine au premier \n et
125 # de limiter la longueur de la chaine a 30 caracteres. Cependant
126 # ceci provoque une perte d'information pour l'utilisateur
127 # Pour le moment on retourne la chaine telle que
132 Retourne une chaine de caractere representant la valeur de self
135 if type(val) == types.FloatType :
136 clefobj=self.GetNomConcept()
137 if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
138 if self.jdc.appli.appliEficas.appliEficas.dict_reels[clefobj].has_key(val):
139 return self.jdc.appli.appliEficas.dict_reels[clefobj][val]
140 if type(val) != types.TupleType :
142 return val.get_name()
149 s=s+item.get_name()+','
156 for typ in self.definition.type:
158 if typ == types.BooleanType: return True
165 Methode booleenne qui retourne 1 si l'objet attend un objet ASSD
166 qui n'existe pas encore (type CO()), 0 sinon
168 for typ in self.definition.type:
169 if type(typ) == types.ClassType or isinstance(typ,type):
170 if issubclass(typ,CO) :
176 Methode booleenne qui retourne 1 si le MCS attend un objet de type ASSD
179 for typ in self.definition.type:
180 if type(typ) == types.ClassType or isinstance(typ,type):
181 if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
185 def wait_assd_or_geom(self):
187 Retourne 1 si le mot-cle simple attend un objet de type
188 assd, ASSD, geom ou GEOM
189 Retourne 0 dans le cas contraire
191 for typ in self.definition.type:
192 if type(typ) == types.ClassType or isinstance(typ,type):
193 if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
199 Retourne 1 si le mot-cle simple attend un objet de type GEOM
200 Retourne 0 dans le cas contraire
202 for typ in self.definition.type:
203 if type(typ) == types.ClassType or isinstance(typ,type):
204 if issubclass(typ,GEOM) : return 1
210 Retourne 1 si le mot-cle simple attend un objet de type TXM
211 Retourne 0 dans le cas contraire
213 for typ in self.definition.type:
214 if typ == 'TXM' :return 1
217 def get_liste_valeurs(self):
220 if self.valeur == None:
222 elif type(self.valeur) == types.TupleType:
223 return list(self.valeur)
224 elif type(self.valeur) == types.ListType:
230 return self.definition.statut=='o'
232 def isImmuable(self):
233 return self.definition.statut=='i'
236 def valid_val(self,valeur):
238 Verifie que la valeur passee en argument (valeur) est valide
239 sans modifier la valeur courante
241 lval=listProto.adapt(valeur)
244 mess=tr("None n'est pas une valeur autorisee")
248 self.typeProto.adapt(val)
249 self.intoProto.adapt(val)
250 self.cardProto.adapt(lval)
251 if self.definition.validators:
252 self.definition.validators.convert(lval)
254 except ValError as e:
259 def valid_valeur(self,new_valeur):
261 Verifie que la valeur passee en argument (new_valeur) est valide
262 sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
264 validite,mess=self.valid_val(new_valeur)
267 def valid_valeur_partielle(self,new_valeur):
269 Verifie que la valeur passee en argument (new_valeur) est une liste partiellement valide
270 sans modifier la valeur courante du mot cle
274 for val in new_valeur:
275 self.typeProto.adapt(val)
276 self.intoProto.adapt(val)
277 #on ne verifie pas la cardinalite
278 if self.definition.validators:
279 validite=self.definition.validators.valide_liste_partielle(new_valeur)
280 except ValError as e:
285 def update_condition_bloc(self):
286 """ Met a jour les blocs conditionnels dependant du mot cle simple self
288 if self.definition.position == 'global' :
289 self.etape.deep_update_condition_bloc()
290 elif self.definition.position == 'global_jdc' :
291 self.jdc.deep_update_condition_bloc()
293 self.parent.update_condition_bloc()
295 def set_valeur(self,new_valeur,evaluation='oui'):
296 #print "set_valeur",new_valeur
298 self.valeur = new_valeur
299 self.val = new_valeur
300 self.update_condition_bloc()
301 self.etape.modified()
305 def eval_valeur(self,new_valeur):
307 Essaie d'evaluer new_valeur comme une SD, une declaration Python
308 ou un EVAL: Retourne la valeur evaluee (ou None) et le test de reussite (1 ou 0)
310 sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
311 #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
315 lsd = self.jdc.cherche_list_avant(self.etape,new_valeur)
320 # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
323 objet = eval(new_valeur,d)
326 itparam=self.cherche_item_parametre(new_valeur)
330 object=eval(new_valeur.valeur,d)
333 if CONTEXT.debug : traceback.print_exc()
336 def eval_val(self,new_valeur):
338 Tente d'evaluer new_valeur comme un objet du jdc (par appel a eval_val_item)
339 ou comme une liste de ces memes objets
340 Si new_valeur contient au moins un separateur (,), tente l'evaluation sur
343 if new_valeur in ('True','False') and 'TXM' in self.definition.type :
344 valeur=self.eval_val_item(str(new_valeur))
346 if type(new_valeur) in (types.ListType,types.TupleType):
348 for item in new_valeur :
349 valeurretour.append(self.eval_val_item(item))
352 valeur=self.eval_val_item(new_valeur)
355 def eval_val_item(self,new_valeur):
357 Tente d'evaluer new_valeur comme un concept, un parametre, un objet Python
358 Si c'est impossible retourne new_valeur inchange
359 argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
361 if self.etape and self.etape.parent:
362 valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
369 #traceback.print_exc()
373 def cherche_item_parametre (self,new_valeur):
375 nomparam=new_valeur[0:new_valeur.find("[")]
376 indice=new_valeur[new_valeur.find(u"[")+1:new_valeur.find(u"]")]
377 for p in self.jdc.params:
378 if p.nom == nomparam :
379 if int(indice) < len(p.get_valeurs()):
380 itparam=parametre.ITEM_PARAMETRE(p,int(indice))
386 def update_concept(self,sd):
387 if type(self.valeur) in (types.ListType,types.TupleType) :
388 if sd in self.valeur:
392 if sd == self.valeur:
396 def delete_concept(self,sd):
401 Met a jour la valeur du mot cle simple suite a la disparition
403 Attention aux matrices
405 if type(self.valeur) == types.TupleType :
406 if sd in self.valeur:
408 self.valeur=list(self.valeur)
409 self.valeur.remove(sd)
411 elif type(self.valeur) == types.ListType:
412 if sd in self.valeur:
414 self.valeur.remove(sd)
417 if self.valeur == sd:
422 # Glut Horrible pour les matrices ???
423 if sd.__class__.__name__== "variable":
424 for type_permis in self.definition.type:
425 if type(type_permis) == types.InstanceType:
426 if type_permis.__class__.__name__ == 'Matrice' :
431 def replace_concept(self,old_sd,sd):
434 - old_sd=concept remplace
437 Met a jour la valeur du mot cle simple suite au remplacement
440 #print "replace_concept",old_sd,sd
441 if type(self.valeur) == types.TupleType :
442 if old_sd in self.valeur:
444 self.valeur=list(self.valeur)
445 i=self.valeur.index(old_sd)
448 elif type(self.valeur) == types.ListType:
449 if old_sd in self.valeur:
451 i=self.valeur.index(old_sd)
455 if self.valeur == old_sd:
461 def set_valeur_co(self,nom_co):
463 Affecte a self l'objet de type CO et de nom nom_co
465 #print "set_valeur_co",nom_co
466 step=self.etape.parent
467 if nom_co == None or nom_co == '':
470 # Avant de creer un concept il faut s'assurer du contexte : step
472 sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
474 # Si un concept du meme nom existe deja dans la portee de l'etape
475 # on ne cree pas le concept
476 return 0,tr("un concept de meme nom existe deja")
477 # Il n'existe pas de concept de meme nom. On peut donc le creer
478 # Il faut neanmoins que la methode NommerSdProd de step gere les
479 # contextes en mode editeur
480 # Normalement la methode du Noyau doit etre surchargee
481 # On declare l'etape du mot cle comme etape courante pour NommerSdprod
482 cs= CONTEXT.get_current_step()
483 CONTEXT.unset_current_step()
484 CONTEXT.set_current_step(step)
485 step.set_etape_context(self.etape)
486 new_objet = Accas.CO(nom_co)
487 CONTEXT.unset_current_step()
488 CONTEXT.set_current_step(cs)
490 self.valeur = new_objet
492 # On force l'enregistrement de new_objet en tant que concept produit
493 # de la macro en appelant get_type_produit avec force=1
494 self.etape.get_type_produit(force=1)
497 #print "set_valeur_co",new_objet
498 return 1,tr("Concept cree")
500 def verif_existence_sd(self):
502 Verifie que les structures de donnees utilisees dans self existent bien dans le contexte
503 avant etape, sinon enleve la referea ces concepts
505 #print "verif_existence_sd"
506 # Attention : possible probleme avec include
507 # A priori il n'y a pas de raison de retirer les concepts non existants
508 # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
509 l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()
510 if type(self.valeur) in (types.TupleType,types.ListType) :
512 for sd in self.valeur:
513 if isinstance(sd,ASSD) :
514 if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
518 if len(l) < len(self.valeur):
523 if isinstance(self.valeur,ASSD) :
524 if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
529 def get_min_max(self):
531 Retourne les valeurs min et max admissibles pour la valeur de self
533 return self.definition.min,self.definition.max
538 Retourne le type attendu par le mot-cle simple
540 return self.definition.type
542 def delete_mc_global(self):
543 """ Retire self des declarations globales
545 if self.definition.position == 'global' :
546 etape = self.get_etape()
548 del etape.mc_globaux[self.nom]
549 elif self.definition.position == 'global_jdc' :
550 del self.jdc.mc_globaux[self.nom]
552 def update_mc_global(self):
554 Met a jour les mots cles globaux enregistres dans l'etape parente
555 et dans le jdc parent.
556 Un mot cle simple peut etre global.
558 if self.definition.position == 'global' :
559 etape = self.get_etape()
561 etape.mc_globaux[self.nom]=self
562 elif self.definition.position == 'global_jdc' :
564 self.jdc.mc_globaux[self.nom]=self
566 def nbrColonnes(self):
567 genea = self.get_genealogie()
568 if "VALE_C" in genea and "DEFI_FONCTION" in genea : return 3
569 if "VALE" in genea and "DEFI_FONCTION" in genea : return 2
572 def valide_item(self,item):
573 """Valide un item isole. Cet item est candidata l'ajout a la liste existante"""
577 self.typeProto.adapt(item)
578 #on verifie les choix possibles
579 self.intoProto.adapt(item)
580 #on ne verifie pas la cardinalite
581 if self.definition.validators:
582 valid=self.definition.validators.verif_item(item)
583 except ValError as e:
584 #traceback.print_exc()
588 def verif_type(self,item):
589 """Verifie le type d'un item de liste"""
592 self.typeProto.adapt(item)
593 #on verifie les choix possibles
594 self.intoProto.adapt(item)
595 #on ne verifie pas la cardinalite mais on verifie les validateurs
596 if self.definition.validators:
597 valid=self.definition.validators.verif_item(item)
600 except ValError as e:
601 #traceback.print_exc()
602 comment=tr(e.__str__())
606 def valideMatrice(self,cr):
607 print "jjjjjjjjjjjjjjjj"
608 #Attention, la matrice contient comme dernier tuple l ordre des variables
609 if self.monType.methodeCalculTaille != None :
610 apply (MCSIMP.__dict__[self.monType.methodeCalculTaille],(self,))
614 if len(self.valeur) == self.monType.nbLigs +1:
616 for i in range(len(self.valeur) -1):
617 if len(self.valeur[i])!= self.monType.nbCols:
626 self.cr.fatal(tr("La matrice n'est pas une matrice %(n_lign)d sur %(n_col)d", \
627 {'n_lign': self.monType.nbLigs, 'n_col': self.monType.nbCols}))
631 def NbDeVariables(self):
632 listeVariables=self.jdc.get_variables(self.etape)
633 self.monType.nbLigs=len(listeVariables)
634 self.monType.nbCols=len(listeVariables)
637 def NbDeDistributions(self):
638 listeVariables=self.jdc.get_distributions(self.etape)
639 self.monType.nbLigs=len(listeVariables)
640 self.monType.nbCols=len(listeVariables)
642 #--------------------------------------------------------------------------------
644 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
645 # Elles doivent etre reintegrees des que possible
648 def verif_typeihm(self,val,cr='non'):
653 traceback.print_exc()
655 return self.verif_type(val,cr)
657 def verif_typeliste(self,val,cr='non') :
660 verif=verif+self.verif_typeihm(v,cr)
663 def init_modif_up(self):
664 Validation.V_MCSIMP.MCSIMP.init_modif_up(self)
665 CONNECTOR.Emit(self,"valid")