Salome HOME
CCAR: merge de la version de developpement V1_12a2 dans la branche principale
[tools/eficas.git] / Ihm / I_MCSIMP.py
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.
9 #
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.
14 #
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.
18 #
19 #
20 # ======================================================================
21 import types,string
22 import traceback
23 from copy import copy
24 from repr import Repr
25 myrepr = Repr()
26 myrepr.maxstring = 100
27 myrepr.maxother = 100
28
29 from Noyau.N_utils import repr_float
30
31 # Attention : les classes ASSD,.... peuvent etre surchargées
32 # dans le package Accas. Il faut donc prendre des précautions si
33 # on utilise les classes du Noyau pour faire des tests (isxxxx, ...)
34 # Si on veut créer des objets comme des CO avec les classes du noyau
35 # ils n'auront pas les conportements des autres packages (pb!!!)
36 # Il vaut mieux les importer d'Accas mais problème d'import circulaire,
37 # on ne peut pas les importer au début.
38 # On fait donc un import local quand c'est nécessaire (peut occasionner
39 # des pbs de prformance).
40 from Noyau.N_ASSD import ASSD,assd
41 from Noyau.N_GEOM import GEOM,geom
42 from Noyau.N_CO import CO
43 import Accas
44 # fin attention
45
46 from Extensions import parametre
47 from Extensions import param2
48 import I_OBJECT
49 import CONNECTOR
50 from I_VALIDATOR import ValError,listProto
51
52 class MCSIMP(I_OBJECT.OBJECT):
53
54   def GetNomConcept(self):
55       p=self
56       while p.parent :
57          try :
58             nomconcept=p.get_sdname()
59             return nomconcept
60          except:
61             try :
62                nomconcept= p.object.get_sdname()
63                return nomconcept
64             except :
65                pass
66          p=p.parent
67       return ""
68
69   def GetText(self):
70     """
71         Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
72         pointé par self
73     """
74
75     if self.valeur == None : 
76       return None
77     elif type(self.valeur) == types.FloatType : 
78       # Traitement d'un flottant isolé
79       txt = str(self.valeur)
80       clefobj=self.GetNomConcept()
81       if self.jdc.appli.dict_reels.has_key(clefobj):
82         if self.jdc.appli.dict_reels[clefobj].has_key(self.valeur):
83            txt=self.jdc.appli.dict_reels[clefobj][self.valeur]
84     elif type(self.valeur) in (types.ListType,types.TupleType) :
85       # Traitement des listes
86       txt='('
87       sep=''
88       for val in self.valeur:
89         if type(val) == types.FloatType : 
90            clefobj=self.GetNomConcept()
91            if self.jdc.appli.dict_reels.has_key(clefobj):
92               if self.jdc.appli.dict_reels[clefobj].has_key(val):
93                  txt=txt + sep +self.jdc.appli.dict_reels[clefobj][val]
94               else :
95                  txt=txt + sep + str(val)
96            else :
97               txt=txt + sep + str(val)
98         else: 
99            txt = txt + sep+ str(val)
100         if len(txt) > 200:
101             #ligne trop longue, on tronque
102             txt=txt+" ..."
103             break
104         sep=','
105       txt=txt+')'
106     else:
107       # Traitement des autres cas
108       txt = str(self.valeur)
109
110     # txt peut etre une longue chaine sur plusieurs lignes.
111     # Il est possible de tronquer cette chaine au premier \n et 
112     # de limiter la longueur de la chaine a 30 caracteres. Cependant
113     # ceci provoque une perte d'information pour l'utilisateur
114     # Pour le moment on retourne la chaine telle que
115     return txt
116
117   def getval(self):
118     """ 
119        Retourne une chaîne de caractère représentant la valeur de self 
120     """
121     val=self.valeur
122     if type(val) == types.FloatType : 
123       clefobj=self.GetNomConcept()
124       if self.jdc.appli.dict_reels.has_key(clefobj):
125         if self.jdc.appli.dict_reels[clefobj].has_key(val):
126            return self.jdc.appli.dict_reels[clefobj][val]
127     if type(val) != types.TupleType :
128       try:
129         return val.get_name()
130       except:
131         return val
132     else :
133       s='( '
134       for item in val :
135         try :
136           s=s+item.get_name()+','
137         except:
138           s=s+`item`+','
139       s=s+' )'
140       return s
141
142   def wait_co(self):
143     """
144         Méthode booléenne qui retourne 1 si l'objet attend un objet ASSD 
145         qui n'existe pas encore (type CO()), 0 sinon
146     """
147     for typ in self.definition.type:
148       if type(typ) == types.ClassType or isinstance(typ,type):
149         if issubclass(typ,CO) :
150            return 1
151     return 0
152
153   def wait_assd(self):
154     """ 
155         Méthode booléenne qui retourne 1 si le MCS attend un objet de type ASSD 
156         ou dérivé, 0 sinon
157     """
158     for typ in self.definition.type:
159       if type(typ) == types.ClassType or isinstance(typ,type):
160         if issubclass(typ,ASSD) and not issubclass(typ,GEOM):
161           return 1
162     return 0
163
164   def wait_assd_or_geom(self):
165     """ 
166          Retourne 1 si le mot-clé simple attend un objet de type
167          assd, ASSD, geom ou GEOM
168          Retourne 0 dans le cas contraire
169     """
170     for typ in self.definition.type:
171       if type(typ) == types.ClassType or isinstance(typ,type):
172         if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) :
173           return 1
174     return 0
175
176   def wait_geom(self):
177     """ 
178          Retourne 1 si le mot-clé simple attend un objet de type GEOM
179          Retourne 0 dans le cas contraire
180     """
181     for typ in self.definition.type:
182       if type(typ) == types.ClassType or isinstance(typ,type):
183         if issubclass(typ,GEOM) : return 1
184     return 0
185
186   def wait_TXM(self):
187     """ 
188          Retourne 1 si le mot-clé simple attend un objet de type TXM
189          Retourne 0 dans le cas contraire
190     """
191     for typ in self.definition.type:
192       if typ == 'TXM' :return 1
193     return 0
194
195   def get_liste_valeurs(self):
196     """
197     """
198     if self.valeur == None:
199       return []
200     elif type(self.valeur) == types.TupleType:
201       return list(self.valeur)
202     elif type(self.valeur) == types.ListType:
203       return self.valeur
204     else:
205       return [self.valeur]
206
207   def isoblig(self):
208     return self.definition.statut=='o'
209
210   def valid_val(self,valeur):
211       """
212         Verifie que la valeur passee en argument (valeur) est valide
213         sans modifier la valeur courante 
214       """
215       lval=listProto.adapt(valeur)
216       if lval is None:
217          valid=0
218          mess="None n'est pas une valeur autorisée"
219       else:
220          try:
221             for val in lval:
222                 self.typeProto.adapt(val)
223                 self.intoProto.adapt(val)
224             self.cardProto.adapt(lval)
225             if self.definition.validators:
226                 self.definition.validators.convert(lval)
227             valid,mess=1,""
228          except ValError,e:
229             mess=str(e)
230             valid=0
231       return valid,mess
232
233   def valid_valeur(self,new_valeur):
234       """
235         Verifie que la valeur passee en argument (new_valeur) est valide
236         sans modifier la valeur courante (evite d'utiliser set_valeur et est plus performant)
237       """
238       validite,mess=self.valid_val(new_valeur)
239       return validite
240
241   def valid_valeur_partielle(self,new_valeur):
242       """
243         Verifie que la valeur passee en argument (new_valeur) est une liste partiellement valide
244         sans modifier la valeur courante du mot cle
245       """
246       validite=1
247       try:
248           for val in new_valeur:
249               self.typeProto.adapt(val)
250               self.intoProto.adapt(val)
251               #on ne verifie pas la cardinalité
252               if self.definition.validators:
253                   validite=self.definition.validators.valide_liste_partielle(new_valeur)
254       except ValError,e:
255           validite=0
256
257       return validite
258
259   def update_condition_bloc(self):
260       """ Met a jour les blocs conditionnels dependant du mot cle simple self
261       """
262       if self.definition.position == 'global' : 
263          self.etape.deep_update_condition_bloc()
264       elif self.definition.position == 'global_jdc' :
265          self.jdc.deep_update_condition_bloc()
266       else:
267          self.parent.update_condition_bloc()
268
269   def set_valeur(self,new_valeur,evaluation='oui'):
270         #print "set_valeur",new_valeur
271         self.init_modif()
272         self.valeur = new_valeur
273         self.val = new_valeur
274         self.update_condition_bloc()
275         self.fin_modif()
276         return 1
277
278   def eval_valeur(self,new_valeur):
279     """
280         Essaie d'évaluer new_valeur comme une SD, une déclaration Python 
281         ou un EVAL: Retourne la valeur évaluée (ou None) et le test de réussite (1 ou 0)
282     """
283     sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
284     #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
285     #print sd
286     if sd is not None:
287       return sd,1
288     lsd = self.jdc.cherche_list_avant(self.etape,new_valeur) 
289     if lsd :
290       return lsd,1
291     else:
292       d={}
293       # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
294       d['EVAL']=Accas.EVAL
295       try :
296         objet = eval(new_valeur,d)
297         return objet,1
298       except Exception:
299         itparam=self.cherche_item_parametre(new_valeur)
300         if itparam:
301              return itparam,1
302         try :
303              object=eval(new_valeur.valeur,d)
304         except :
305              pass
306         if CONTEXT.debug : traceback.print_exc()
307         return None,0
308
309   def eval_val(self,new_valeur):
310     """
311        Tente d'evaluer new_valeur comme un objet du jdc (par appel a eval_val_item)
312        ou comme une liste de ces memes objets
313        Si new_valeur contient au moins un separateur (,), tente l'evaluation sur
314        la chaine splittee
315     """
316     if type(new_valeur) in (types.ListType,types.TupleType):
317        valeurretour=[]
318        for item in new_valeur :
319           valeurretour.append(self.eval_val_item(item))
320        return valeurretour
321     else:
322        valeur=self.eval_val_item(new_valeur)
323        return valeur
324
325   def eval_val_item(self,new_valeur):
326     """
327        Tente d'evaluer new_valeur comme un concept, un parametre, un objet Python
328        Si c'est impossible retourne new_valeur inchange
329        argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
330     """
331     if self.etape and self.etape.parent:
332        valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
333        return valeur
334     else:
335        try :
336            valeur = eval(val)
337            return valeur
338        except:
339            #traceback.print_exc()
340            return new_valeur
341            pass
342
343   def cherche_item_parametre (self,new_valeur):
344         try:
345           nomparam=new_valeur[0:new_valeur.find("[")]
346           indice=new_valeur[new_valeur.find("[")+1:new_valeur.find("]")]
347           for p in self.jdc.params:
348              if p.nom == nomparam :
349                 if int(indice) < len(p.get_valeurs()):
350                    itparam=parametre.ITEM_PARAMETRE(p,int(indice))
351                    return itparam
352           return None
353         except:
354           return None
355
356   def update_concept(self,sd):
357     if type(self.valeur) in (types.ListType,types.TupleType) :
358        if sd in self.valeur:self.fin_modif()
359     else:
360        if sd == self.valeur:self.fin_modif()
361
362   def delete_concept(self,sd):
363     """ 
364         Inputs :
365            - sd=concept detruit
366         Fonction :
367         Met a jour la valeur du mot cle simple suite à la disparition 
368         du concept sd
369     """
370     #print "delete_concept",sd
371     if type(self.valeur) == types.TupleType :
372       if sd in self.valeur:
373         self.init_modif()
374         self.valeur=list(self.valeur)
375         self.valeur.remove(sd)
376         self.fin_modif()
377     elif type(self.valeur) == types.ListType:
378       if sd in self.valeur:
379         self.init_modif()
380         self.valeur.remove(sd)
381         self.fin_modif()
382     else:
383       if self.valeur == sd:
384         self.init_modif()
385         self.valeur=None
386         self.val=None
387         self.fin_modif()
388
389   def replace_concept(self,old_sd,sd):
390     """
391         Inputs :
392            - old_sd=concept remplacé
393            - sd=nouveau concept
394         Fonction :
395         Met a jour la valeur du mot cle simple suite au remplacement 
396         du concept old_sd
397     """
398     #print "replace_concept",old_sd,sd
399     if type(self.valeur) == types.TupleType :
400       if old_sd in self.valeur:
401         self.init_modif()
402         self.valeur=list(self.valeur)
403         i=self.valeur.index(old_sd)
404         self.valeur[i]=sd
405         self.fin_modif()
406     elif type(self.valeur) == types.ListType:
407       if old_sd in self.valeur:
408         self.init_modif()
409         i=self.valeur.index(old_sd)
410         self.valeur[i]=sd
411         self.fin_modif()
412     else:
413       if self.valeur == old_sd:
414         self.init_modif()
415         self.valeur=sd
416         self.val=sd
417         self.fin_modif()
418
419   def set_valeur_co(self,nom_co):
420       """
421           Affecte à self l'objet de type CO et de nom nom_co
422       """
423       #print "set_valeur_co",nom_co
424       step=self.etape.parent
425       if nom_co == None or nom_co == '':
426          new_objet=None
427       else:
428          # Avant de créer un concept il faut s'assurer du contexte : step 
429          # courant
430          sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui')
431          if sd:
432             # Si un concept du meme nom existe deja dans la portée de l'étape
433             # on ne crée pas le concept
434             return 0,"un concept de meme nom existe deja"
435          # Il n'existe pas de concept de meme nom. On peut donc le créer 
436          # Il faut néanmoins que la méthode NommerSdProd de step gère les 
437          # contextes en mode editeur
438          # Normalement la méthode  du Noyau doit etre surchargée
439          # On déclare l'étape du mot clé comme etape courante pour NommerSdprod
440          cs= CONTEXT.get_current_step()
441          CONTEXT.unset_current_step()
442          CONTEXT.set_current_step(step)
443          step.set_etape_context(self.etape)
444          new_objet = Accas.CO(nom_co)
445          CONTEXT.unset_current_step()
446          CONTEXT.set_current_step(cs)
447       self.init_modif()
448       self.valeur = new_objet
449       self.val = new_objet
450       # On force l'enregistrement de new_objet en tant que concept produit 
451       # de la macro en appelant get_type_produit avec force=1
452       self.etape.get_type_produit(force=1)
453       self.fin_modif()
454       step.reset_context()
455       #print "set_valeur_co",new_objet
456       return 1,"Concept créé"
457         
458   def verif_existence_sd(self):
459      """
460         Vérifie que les structures de données utilisées dans self existent bien dans le contexte
461         avant étape, sinon enlève la référence à ces concepts
462      """
463      #print "verif_existence_sd"
464      # Attention : possible probleme avec include
465      # A priori il n'y a pas de raison de retirer les concepts non existants
466      # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
467      l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()  
468      if type(self.valeur) in (types.TupleType,types.ListType) :
469        l=[]
470        for sd in self.valeur:
471          if isinstance(sd,ASSD) :
472             if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
473                l.append(sd)
474          else:
475             l.append(sd)
476        if len(l) < len(self.valeur):
477           self.init_modif()
478           self.valeur=tuple(l)
479           self.fin_modif()
480      else:
481        if isinstance(self.valeur,ASSD) :
482           if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
483              self.init_modif()
484              self.valeur = None
485              self.fin_modif()
486  
487   def get_min_max(self):
488      """
489      Retourne les valeurs min et max admissibles pour la valeur de self
490      """
491      return self.definition.min,self.definition.max
492
493
494   def get_type(self):
495      """
496      Retourne le type attendu par le mot-clé simple
497      """
498      return self.definition.type
499
500   def delete_mc_global(self):
501       """ Retire self des declarations globales
502       """
503       if self.definition.position == 'global' : 
504          etape = self.get_etape()
505          if etape :
506             del etape.mc_globaux[self.nom]
507       elif self.definition.position == 'global_jdc' :
508          del self.jdc.mc_globaux[self.nom]
509
510   def update_mc_global(self):
511      """
512         Met a jour les mots cles globaux enregistrés dans l'étape parente
513         et dans le jdc parent.
514         Un mot cle simple peut etre global. 
515      """
516      if self.definition.position == 'global' :
517         etape = self.get_etape()
518         if etape :
519            etape.mc_globaux[self.nom]=self
520      elif self.definition.position == 'global_jdc' :
521         if self.jdc:
522            self.jdc.mc_globaux[self.nom]=self
523
524   def nbrColonnes(self):
525      genea = self.get_genealogie()
526      if "VALE_C" in genea and "DEFI_FONCTION" in genea : return 3
527      if "VALE" in genea and "DEFI_FONCTION" in genea : return 2
528      return 0
529
530   def valide_item(self,item):
531       """Valide un item isolé. Cet item est candidat à l'ajout à la liste existante"""
532       valid=1
533       try:
534           #on verifie le type
535           self.typeProto.adapt(item)
536           #on verifie les choix possibles
537           self.intoProto.adapt(item)
538           #on ne verifie pas la cardinalité
539           if self.definition.validators:
540               valid=self.definition.validators.verif_item(item)
541       except ValError,e:
542           #traceback.print_exc()
543           valid=0
544       return valid
545
546   def verif_type(self,item):
547       """Verifie le type d'un item de liste"""
548       try:
549           #on verifie le type
550           self.typeProto.adapt(item)
551           #on verifie les choix possibles
552           self.intoProto.adapt(item)
553           #on ne verifie pas la cardinalité mais on verifie les validateurs
554           if self.definition.validators:
555               valid=self.definition.validators.verif_item(item)
556           comment=""
557           valid=1
558       except ValError,e:
559           #traceback.print_exc()
560           comment=str(e)
561           valid=0
562       return valid,comment
563
564 #--------------------------------------------------------------------------------
565  
566 #ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
567 # Elles doivent etre reintegrees des que possible
568
569
570   def verif_typeihm(self,val,cr='non'):
571       try :
572          val.eval()
573          return 1
574       except :
575          traceback.print_exc()
576          pass
577       return self.verif_type(val,cr)
578
579   def verif_typeliste(self,val,cr='non') :
580       verif=0
581       for v in val :
582         verif=verif+self.verif_typeihm(v,cr)
583       return verif
584