]> SALOME platform Git repositories - tools/eficas.git/blob - Ihm/I_MCSIMP.py
Salome HOME
modif du 1010
[tools/eficas.git] / Ihm / I_MCSIMP.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013   EDF R&D
3 #
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.
8 #
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.
13 #
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
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 import types,string
21 import traceback
22 from copy import copy
23 from repr import Repr
24 from Extensions.i18n import tr
25 from Extensions.eficas_exception import EficasException
26 myrepr = Repr()
27 myrepr.maxstring = 100
28 myrepr.maxother = 100
29
30 from Noyau.N_utils import repr_float
31 import Validation
32 import CONNECTOR
33
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
46 import Accas
47 # fin attention
48
49 from Extensions import parametre
50 from Extensions import param2
51 import I_OBJECT
52 import CONNECTOR
53 from I_VALIDATOR import ValError,listProto
54
55 class MCSIMP(I_OBJECT.OBJECT):
56
57
58   def isvalid(self,cr='non'):
59       if self.state == 'unchanged':
60         return self.valid
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)
66
67   def GetNomConcept(self):
68       p=self
69       while p.parent :
70          try :
71             nomconcept=p.get_sdname()
72             return nomconcept
73          except:
74             try :
75                nomconcept= p.object.get_sdname()
76                return nomconcept
77             except :
78                pass
79          p=p.parent
80       return ""
81
82   def GetText(self):
83     """
84         Retourne le texte a afficher dans l'arbre representant la valeur de l'objet
85         pointe par self
86     """
87
88     if self.valeur == None : 
89       return 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       if self.valeur==[] or self.valeur == (): return str(self.valeur)
99       # Traitement des listes
100       txt='('
101       sep=''
102       for val in self.valeur:
103         if type(val) == types.FloatType : 
104            clefobj=self.GetNomConcept()
105            if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
106               if self.jdc.appli.appliEficas.dict_reels[clefobj].has_key(val):
107                  txt=txt + sep +self.jdc.appli.appliEficas.dict_reels[clefobj][val]
108               else :
109                  txt=txt + sep + str(val)
110            else :
111               txt=txt + sep + str(val)
112         else: 
113            if isinstance(val,types.TupleType):
114               texteVal='('
115               for i in val :
116                   if isinstance(i, types.StringType) : texteVal = texteVal +"'"+str(i)+"'," 
117                   else : texteVal = texteVal + str(i)+','
118               texteVal=texteVal[:-1]+')'
119            else : 
120               if isinstance(val,types.StringType): texteVal="'"+str(val)+"'"
121               else :texteVal=str(val)
122            txt = txt + sep+ texteVal 
123
124 ##        if len(txt) > 200:
125 ##            #ligne trop longue, on tronque
126 ##            txt=txt+" ..."
127 ##            break
128         sep=','
129       # cas des listes de tuples de longueur 1
130       if isinstance(val,types.TupleType) and len(self.valeur) == 1 : txt=txt+','
131       txt=txt+')'
132     else:
133       # Traitement des autres cas
134       txt = str(self.valeur)
135
136     # txt peut etre une longue chaine sur plusieurs lignes.
137     # Il est possible de tronquer cette chaine au premier \n et 
138     # de limiter la longueur de la chaine a 30 caracteres. Cependant
139     # ceci provoque une perte d'information pour l'utilisateur
140     # Pour le moment on retourne la chaine telle que
141     return txt
142
143   def getval(self):
144     """ 
145        Retourne une chaine de caractere representant la valeur de self 
146     """
147     val=self.valeur
148     if type(val) == types.FloatType : 
149       clefobj=self.GetNomConcept()
150       if self.jdc.appli.appliEficas.dict_reels.has_key(clefobj):
151         if self.jdc.appli.appliEficas.appliEficas.dict_reels[clefobj].has_key(val):
152            return self.jdc.appli.appliEficas.dict_reels[clefobj][val]
153     if type(val) != types.TupleType :
154       try:
155         return val.get_name()
156       except:
157         return val
158     else :
159       if val ==() or val == [] : return val
160       s='( '
161       for item in val :
162         try :
163           s=s+item.get_name()+','
164         except:
165           s=s+`item`+','
166       s=s+' )'
167       return s
168
169   def wait_bool(self):
170       for typ in self.definition.type:
171           try :
172             if typ == types.BooleanType: return True
173           except :
174             pass
175       return False
176
177   def wait_co(self):
178     """
179         Methode booleenne qui retourne 1 si l'objet attend un objet ASSD 
180         qui n'existe pas encore (type CO()), 0 sinon
181     """
182     for typ in self.definition.type:
183       if type(typ) == types.ClassType or isinstance(typ,type):
184         if issubclass(typ,CO) :
185            return 1
186     return 0
187
188   def wait_assd(self):
189     """ 
190         Methode booleenne qui retourne 1 si le MCS attend un objet de type ASSD 
191         ou derive, 0 sinon
192     """
193     for typ in self.definition.type:
194       if type(typ) == types.ClassType or isinstance(typ,type):
195         if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
196           return 1
197     return 0
198
199   def wait_assd_or_geom(self):
200     """ 
201          Retourne 1 si le mot-cle simple attend un objet de type
202          assd, ASSD, geom ou GEOM
203          Retourne 0 dans le cas contraire
204     """
205     for typ in self.definition.type:
206       if type(typ) == types.ClassType or isinstance(typ,type):
207         if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
208           return 1
209     return 0
210
211   def wait_geom(self):
212     """ 
213          Retourne 1 si le mot-cle simple attend un objet de type GEOM
214          Retourne 0 dans le cas contraire
215     """
216     for typ in self.definition.type:
217       if type(typ) == types.ClassType or isinstance(typ,type):
218         if issubclass(typ,GEOM) : return 1
219     return 0
220
221
222   def wait_TXM(self):
223     """ 
224          Retourne 1 si le mot-cle simple attend un objet de type TXM
225          Retourne 0 dans le cas contraire
226     """
227     for typ in self.definition.type:
228       if typ == 'TXM' :return 1
229     return 0
230
231   def get_liste_valeurs(self):
232     """
233     """
234     if self.valeur == None:
235       return []
236     elif type(self.valeur) == types.TupleType:
237       return list(self.valeur)
238     elif type(self.valeur) == types.ListType:
239       return self.valeur
240     else:
241       return [self.valeur]
242
243   def isoblig(self):
244     return self.definition.statut=='o'
245
246   def isImmuable(self):
247     return self.definition.homo=='constant'
248
249   def isInformation(self):
250     return self.definition.homo=='information'
251
252
253
254   def valid_val(self,valeur):
255       """
256         Verifie que la valeur passee en argument (valeur) est valide
257         sans modifier la valeur courante 
258       """
259       lval=listProto.adapt(valeur)
260       if lval is None:
261          valid=0
262          mess=tr("None n'est pas une valeur autorisee")
263       else:
264          try:
265             for val in lval:
266                 self.typeProto.adapt(val)
267                 self.intoProto.adapt(val)
268             self.cardProto.adapt(lval)
269             if self.definition.validators:
270                 self.definition.validators.convert(lval)
271             valid,mess=1,""
272          except ValError as e:
273             mess=str(e)
274             valid=0
275       return valid,mess
276
277   def valid_valeur(self,new_valeur):
278       """
279         Verifie que la valeur passee en argument (new_valeur) est valide
280         sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
281       """
282       validite,mess=self.valid_val(new_valeur)
283       return validite
284
285   def valid_valeur_partielle(self,new_valeur):
286       """
287         Verifie que la valeur passee en argument (new_valeur) est une liste partiellement valide
288         sans modifier la valeur courante du mot cle
289       """
290       validite=1
291       try:
292           for val in new_valeur:
293               self.typeProto.adapt(val)
294               self.intoProto.adapt(val)
295               #on ne verifie pas la cardinalite
296               if self.definition.validators:
297                   validite=self.definition.validators.valide_liste_partielle(new_valeur)
298       except ValError as e:
299           validite=0
300
301       return validite
302
303   def update_condition_bloc(self):
304       """ Met a jour les blocs conditionnels dependant du mot cle simple self
305       """
306       if self.definition.position == 'global' : 
307          self.etape.deep_update_condition_bloc()
308       elif self.definition.position == 'global_jdc' :
309          self.jdc.deep_update_condition_bloc()
310       else:
311          self.parent.update_condition_bloc()
312
313   def set_valeur(self,new_valeur,evaluation='oui'):
314         #print "set_valeur",new_valeur
315         self.init_modif()
316         self.valeur = new_valeur
317         self.val = new_valeur
318         self.update_condition_bloc()
319         self.etape.modified()
320         self.fin_modif()
321         return 1
322
323   def eval_valeur(self,new_valeur):
324     """
325         Essaie d'evaluer new_valeur comme une SD, une declaration Python 
326         ou un EVAL: Retourne la valeur evaluee (ou None) et le test de reussite (1 ou 0)
327     """
328     sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
329     #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
330     #print sd
331     if sd is not None:
332       return sd,1
333     lsd = self.jdc.cherche_list_avant(self.etape,new_valeur) 
334     if lsd :
335       return lsd,1
336     else:
337       d={}
338       # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
339       d['EVAL']=Accas.EVAL
340       try :
341         objet = eval(new_valeur,d)
342         return objet,1
343       except Exception:
344         itparam=self.cherche_item_parametre(new_valeur)
345         if itparam:
346              return itparam,1
347         try :
348              object=eval(new_valeur.valeur,d)
349         except :
350              pass
351         if CONTEXT.debug : traceback.print_exc()
352         return None,0
353
354   def eval_val(self,new_valeur):
355     """
356        Tente d'evaluer new_valeur comme un objet du jdc (par appel a eval_val_item)
357        ou comme une liste de ces memes objets
358        Si new_valeur contient au moins un separateur (,), tente l'evaluation sur
359        la chaine splittee
360     """
361     if new_valeur in ('True','False') and 'TXM' in self.definition.type  :
362        valeur=self.eval_val_item(str(new_valeur))
363        return new_valeur
364     if type(new_valeur) in (types.ListType,types.TupleType):
365        valeurretour=[]
366        for item in new_valeur :
367           valeurretour.append(self.eval_val_item(item))
368        return valeurretour
369     else:
370        valeur=self.eval_val_item(new_valeur)
371        return valeur
372
373   def eval_val_item(self,new_valeur):
374     """
375        Tente d'evaluer new_valeur comme un concept, un parametre, un objet Python
376        Si c'est impossible retourne new_valeur inchange
377        argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
378     """
379     if self.etape and self.etape.parent:
380        valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
381        return valeur
382     else:
383        try :
384            valeur = eval(val)
385            return valeur
386        except:
387            #traceback.print_exc()
388            return new_valeur
389            pass
390
391   def cherche_item_parametre (self,new_valeur):
392         try:
393           nomparam=new_valeur[0:new_valeur.find("[")]
394           indice=new_valeur[new_valeur.find(u"[")+1:new_valeur.find(u"]")]
395           for p in self.jdc.params:
396              if p.nom == nomparam :
397                 if int(indice) < len(p.get_valeurs()):
398                    itparam=parametre.ITEM_PARAMETRE(p,int(indice))
399                    return itparam
400           return None
401         except:
402           return None
403
404   def update_concept(self,sd):
405     if type(self.valeur) in (types.ListType,types.TupleType) :
406        if sd in self.valeur:
407          self.init_modif()
408          self.fin_modif()
409     else:
410        if sd == self.valeur:
411          self.init_modif()
412          self.fin_modif()
413
414   def delete_concept(self,sd):
415     """ 
416         Inputs :
417            - sd=concept detruit
418         Fonction :
419         Met a jour la valeur du mot cle simple suite a la disparition 
420         du concept sd
421         Attention aux matrices
422     """
423     if type(self.valeur) == types.TupleType :
424       if sd in self.valeur:
425         self.init_modif()
426         self.valeur=list(self.valeur)
427         self.valeur.remove(sd)
428         self.fin_modif()
429     elif type(self.valeur) == types.ListType:
430       if sd in self.valeur:
431         self.init_modif()
432         self.valeur.remove(sd)
433         self.fin_modif()
434     else:
435       if self.valeur == sd:
436         self.init_modif()
437         self.valeur=None
438         self.val=None
439         self.fin_modif()
440     # Glut Horrible pour les matrices ???
441     if sd.__class__.__name__== "variable":
442        for type_permis in self.definition.type:
443             if type(type_permis) == types.InstanceType:
444                if type_permis.__class__.__name__ == 'Matrice' :
445                    self.state="changed"
446                    self.isvalid()
447                   
448
449   def replace_concept(self,old_sd,sd):
450     """
451         Inputs :
452            - old_sd=concept remplace
453            - sd=nouveau concept
454         Fonction :
455         Met a jour la valeur du mot cle simple suite au remplacement 
456         du concept old_sd
457     """
458     #print "replace_concept",old_sd,sd
459     if type(self.valeur) == types.TupleType :
460       if old_sd in self.valeur:
461         self.init_modif()
462         self.valeur=list(self.valeur)
463         i=self.valeur.index(old_sd)
464         self.valeur[i]=sd
465         self.fin_modif()
466     elif type(self.valeur) == types.ListType:
467       if old_sd in self.valeur:
468         self.init_modif()
469         i=self.valeur.index(old_sd)
470         self.valeur[i]=sd
471         self.fin_modif()
472     else:
473       if self.valeur == old_sd:
474         self.init_modif()
475         self.valeur=sd
476         self.val=sd
477         self.fin_modif()
478
479   def set_valeur_co(self,nom_co):
480       """
481           Affecte a self l'objet de type CO et de nom nom_co
482       """
483       #print "set_valeur_co",nom_co
484       step=self.etape.parent
485       if nom_co == None or nom_co == '':
486          new_objet=None
487       else:
488          # Avant de creer un concept il faut s'assurer du contexte : step 
489          # courant
490          sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
491          if sd:
492             # Si un concept du meme nom existe deja dans la portee de l'etape
493             # on ne cree pas le concept
494             return 0,tr("un concept de meme nom existe deja")
495          # Il n'existe pas de concept de meme nom. On peut donc le creer 
496          # Il faut neanmoins que la methode NommerSdProd de step gere les 
497          # contextes en mode editeur
498          # Normalement la methode  du Noyau doit etre surchargee
499          # On declare l'etape du mot cle comme etape courante pour NommerSdprod
500          cs= CONTEXT.get_current_step()
501          CONTEXT.unset_current_step()
502          CONTEXT.set_current_step(step)
503          step.set_etape_context(self.etape)
504          new_objet = Accas.CO(nom_co)
505          CONTEXT.unset_current_step()
506          CONTEXT.set_current_step(cs)
507       self.init_modif()
508       self.valeur = new_objet
509       self.val = new_objet
510       # On force l'enregistrement de new_objet en tant que concept produit 
511       # de la macro en appelant get_type_produit avec force=1
512       self.etape.get_type_produit(force=1)
513       self.fin_modif()
514       step.reset_context()
515       #print "set_valeur_co",new_objet
516       return 1,tr("Concept cree")
517         
518   def verif_existence_sd(self):
519      """
520         Verifie que les structures de donnees utilisees dans self existent bien dans le contexte
521         avant etape, sinon enleve la referea ces concepts
522      """
523      #print "verif_existence_sd"
524      # Attention : possible probleme avec include
525      # A priori il n'y a pas de raison de retirer les concepts non existants
526      # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
527      l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()  
528      if type(self.valeur) in (types.TupleType,types.ListType) :
529        l=[]
530        for sd in self.valeur:
531          if isinstance(sd,ASSD) :
532             if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
533                l.append(sd)
534          else:
535             l.append(sd)
536        if len(l) < len(self.valeur):
537           self.init_modif()
538           self.valeur=tuple(l)
539           self.fin_modif()
540      else:
541        if isinstance(self.valeur,ASSD) :
542           if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
543              self.init_modif()
544              self.valeur = None
545              self.fin_modif()
546  
547   def get_min_max(self):
548      """
549      Retourne les valeurs min et max admissibles pour la valeur de self
550      """
551      return self.definition.min,self.definition.max
552
553
554   def get_type(self):
555      """
556      Retourne le type attendu par le mot-cle simple
557      """
558      return self.definition.type
559
560   def delete_mc_global(self):
561       """ Retire self des declarations globales
562       """
563       if self.definition.position == 'global' : 
564          etape = self.get_etape()
565          if etape :
566             del etape.mc_globaux[self.nom]
567       elif self.definition.position == 'global_jdc' :
568          del self.jdc.mc_globaux[self.nom]
569
570   def update_mc_global(self):
571      """
572         Met a jour les mots cles globaux enregistres dans l'etape parente
573         et dans le jdc parent.
574         Un mot cle simple peut etre global. 
575      """
576      if self.definition.position == 'global' :
577         etape = self.get_etape()
578         if etape :
579            etape.mc_globaux[self.nom]=self
580      elif self.definition.position == 'global_jdc' :
581         if self.jdc:
582            self.jdc.mc_globaux[self.nom]=self
583
584   def nbrColonnes(self):
585      genea = self.get_genealogie()
586      if "VALE_C" in genea and "DEFI_FONCTION" in genea : return 3
587      if "VALE" in genea and "DEFI_FONCTION" in genea : return 2
588      return 0
589
590   def valide_item(self,item):
591       """Valide un item isole. Cet item est candidata l'ajout a la liste existante"""
592       valid=1
593       try:
594           #on verifie le type
595           self.typeProto.adapt(item)
596           #on verifie les choix possibles
597           self.intoProto.adapt(item)
598           #on ne verifie pas la cardinalite
599           if self.definition.validators:
600               valid=self.definition.validators.verif_item(item)
601       except ValError as e:
602           #traceback.print_exc()
603           valid=0
604       return valid
605
606   def verif_type(self,item):
607       """Verifie le type d'un item de liste"""
608       try:
609           #on verifie le type
610           self.typeProto.adapt(item)
611           #on verifie les choix possibles
612           self.intoProto.adapt(item)
613           #on ne verifie pas la cardinalite mais on verifie les validateurs
614           if self.definition.validators:
615               valid=self.definition.validators.verif_item(item)
616           comment=""
617           valid=1
618       except ValError as e:
619           #traceback.print_exc()
620           comment=tr(e.__str__())
621           valid=0
622       return valid,comment
623
624   def valideMatrice(self,cr):
625        #Attention, la matrice contient comme dernier tuple l ordre des variables
626        if self.valideEnteteMatrice()==False :
627            self.set_valid(0)
628            if cr == "oui" : self.cr.fatal(tr("La matrice n'a pas le bon entete"))
629            return 0
630        if self.monType.methodeCalculTaille != None :
631            apply (MCSIMP.__dict__[self.monType.methodeCalculTaille],(self,))
632        try :
633        #if 1 :
634            ok=0
635            if len(self.valeur) == self.monType.nbLigs +1:
636               ok=1
637               for i in range(len(self.valeur) -1):
638                   if len(self.valeur[i])!= self.monType.nbCols:
639                      ok=0
640            if ok: 
641               self.set_valid(1)
642               return 1 
643        except :
644        #else :
645             pass
646        if cr == 'oui' :
647              self.cr.fatal(tr("La matrice n'est pas une matrice %(n_lign)d sur %(n_col)d", \
648              {'n_lign': self.monType.nbLigs, 'n_col': self.monType.nbCols}))
649        self.set_valid(0)
650        return 0
651
652
653   def NbDeVariables(self):
654        listeVariables=self.jdc.get_variables(self.etape)
655        self.monType.nbLigs=len(listeVariables)
656        self.monType.nbCols=len(listeVariables)
657       
658   def valideEnteteMatrice(self):
659       if self.jdc.get_distributions(self.etape) == () or self.valeur == None : return 0
660       if self.jdc.get_distributions(self.etape) != self.valeur[0] : return 0
661       return 1
662      
663   def changeEnteteMatrice(self):
664       a=[self.jdc.get_distributions(self.etape),]
665       for t in self.valeur[1:]:
666          a.append(t)
667       self.valeur=a
668
669
670   def NbDeDistributions(self):
671        listeVariables=self.jdc.get_distributions(self.etape)
672        self.monType.nbLigs=len(listeVariables)
673        self.monType.nbCols=len(listeVariables)
674       
675 #--------------------------------------------------------------------------------
676  
677 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
678 # Elles doivent etre reintegrees des que possible
679
680
681   def verif_typeihm(self,val,cr='non'):
682       try :
683          val.eval()
684          return 1
685       except :
686          traceback.print_exc()
687          pass
688       return self.verif_type(val,cr)
689
690   def verif_typeliste(self,val,cr='non') :
691       verif=0
692       for v in val :
693         verif=verif+self.verif_typeihm(v,cr)
694       return verif
695
696   def init_modif_up(self):
697     Validation.V_MCSIMP.MCSIMP.init_modif_up(self)
698     CONNECTOR.Emit(self,"valid")