Salome HOME
CCAR: diverses corrections lies aux validateurs
[tools/eficas.git] / Editeur / composimp.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 # Modules Python
21 import string,types,os
22 from Tkinter import *
23 import Pmw
24 from tkFileDialog import *
25 from tkMessageBox import showinfo
26 from copy import copy,deepcopy
27 import traceback
28
29 # Modules Eficas
30 import Objecttreeitem
31 import prefs
32 import panels
33 import images
34 from widgets import ListeChoix
35 from widgets import FenetreDeSelection
36
37 from Noyau.N_CR import justify_text
38 from utils import substract_list
39
40
41 class newSIMPPanel(panels.OngletPanel):
42   """
43   Classe virtuelle servant de classe mère à toutes les classes Panel
44   servant à afficher et récupérer la valeur d'un mot-clé simple.
45   Le panel est différent suivant le type de la valeur attendu
46   """
47   def init(self):
48       """
49       Méthode appelée par le constructeur de OngletPanel :
50       construit le notebook à 2 onglets utilisé par tous les panels de
51       tous les mots-clés simples
52       """
53       nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
54       nb.pack(fill = 'both', expand = 1)
55       self.nb=nb
56       nb.add('Valeur', tab_text='Saisir valeur')
57       #nb.add('Commentaire',tab_text='Insérer commentaire')
58       self.makeValeurPage(nb.page('Valeur'))
59       #self.makeCommentairePage(nb.page("Commentaire"))
60       nb.setnaturalsize()
61       
62 # ----------------------------------------------------------------------------------------
63 #   Méthodes utilisées pour l'affectation de la valeur donnée par l'utilisateur
64 #    au mot-clé courant
65 # ----------------------------------------------------------------------------------------
66
67   def reset_old_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
68       """
69           Enregistre  val comme valeur de self.node.item.object SANS 
70           faire de test de validité ni ré-évaluer l'ancienne valeur
71           permet de rester avec des valeurs non entrees et de ne pas 
72           ré-évaluer des entiers par exemple
73       """
74       if self.parent.modified == 'n' : self.parent.init_modif()
75       self.node.item.set_valeur(name)
76       self.parent.appli.affiche_infos(mess)
77       if self.node.item.get_position()=='global':
78            self.node.etape.verif_all()
79       elif self.node.item.get_position()=='global_jdc':
80            self.node.racine.verif_all()
81       else :
82            self.node.parent.verif()
83       self.node.update()
84
85   def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
86       """
87           Enregistre  val comme valeur de self.node.item.object  
88           en evaluant l item et en le validant 
89       """
90       if self.parent.modified == 'n' : self.parent.init_modif()
91       if name != None:
92           valeur = name
93           validite = 1
94       else :
95           valeurentree= self.entry.get()
96           self.entry.delete(0,END)
97           if valeurentree == '': valeurentree=None
98           valeur,validite=self.node.item.eval_valeur(valeurentree)
99           if not validite :
100                 valeur= self.entry.get()
101                 commentaire = "impossible d'évaluer : %s " %`valeurentree`
102                 self.parent.appli.affiche_infos(commentaire)
103                 
104       if validite : 
105          if self.node.item.is_list() :
106             validite=self.node.item.valide_liste_complete(valeur)
107             commentaire=self.node.item.info_erreur_liste()
108          else :
109             validite=self.node.item.valide_item(valeur)
110             commentaire=self.node.item.info_erreur_item()
111  
112       if validite :
113           self.node.item.set_valeur(valeur)
114           self.parent.appli.affiche_infos(mess)
115           if self.node.item.get_position()=='global':
116               self.node.etape.verif_all()
117           elif self.node.item.get_position()=='global_jdc':
118               self.node.racine.verif_all()
119           else :
120               self.node.parent.verif()
121           self.node.update()
122           if self.node.item.isvalid():
123               self.node.parent.select()
124       else :
125           self.parent.appli.affiche_infos(commentaire)
126
127 # ----------------------------------------------------------------------------------------
128 #   Méthodes utilisées pour la manipulation des items dans les listes de choix
129 # ----------------------------------------------------------------------------------------
130   def selectValeur(self,name):
131       self.selected_valeur = name
132
133   def deselectValeur(self,name):
134       self.selectValeur = None
135
136   def sup_valeur(self,name=None):
137       """
138       Supprime la valeur selectionnée de la liste des valeurs et la rajoute
139       à la liste des choix possibles
140       """
141       if hasattr(self,'selected_valeur') :
142          if ( self.selected_valeur != None and self.selected_valeur != ''):
143             liste_valeurs = self.Liste_valeurs.get_liste()
144             liste_valeurs.remove(self.selected_valeur)
145             self.Liste_valeurs.put_liste(liste_valeurs)
146             listeActuelle=self.Liste_valeurs.get_liste()
147             liste_choix=self.node.item.get_liste_possible(listeActuelle)
148             self.Liste_choix.put_liste(liste_choix)
149             self.selected_valeur = None
150
151   def add_choix(self,name=None):
152       """
153       Ajoute le choix selectionné à la liste des valeurs et le retire
154       de la liste des choix possibles
155       """
156       
157       if hasattr(self,'selected_choix') :
158          if (self.selected_choix != None and self.selected_choix != ''):
159             min,max = self.node.item.GetMinMax()
160             liste_valeurs = self.Liste_valeurs.get_liste()
161             if len(liste_valeurs) >= max :
162                 self.parent.appli.affiche_infos("La liste ne peut pas avoir plus de %d éléments" %max)
163                 return
164             liste_valeurs.append(self.selected_choix)
165             self.Liste_valeurs.put_liste(liste_valeurs)
166             listeActuelle=self.Liste_valeurs.get_liste()
167             liste_choix=self.node.item.get_liste_possible(listeActuelle)
168             self.Liste_choix.put_liste(liste_choix)
169             self.selected_choix = None
170
171   def selectChoix(self,name):
172       self.selected_choix = name
173
174   def deselectChoix(self,name):
175       self.selectChoix = None
176       
177   def raisecmd(self,page):
178       try:
179          self.entry.focus()
180       except:
181          pass
182
183 class SHELLPanel(newSIMPPanel):
184   """
185   Classe Panel utilisé pour les mots-clés simples qui attendent un shell pour valeur
186   """
187
188   def makeValeurPage(self,page):
189       """ 
190       Affiche la page concernant l'objet pointé par self qui attend un shell
191       """
192       objet_mc = self.node.item.get_definition()
193       aide = self.gen_aide()
194       aide = justify_text(texte=aide)
195       self.frame = Frame(page)
196       self.frame.place(relx=0,rely=0,relwidth=1,relheight=1)
197       label_aide = Label(self.frame,text = aide)
198       label_aide.place(relx=0.5,rely=0.1,anchor='center')
199       self.text = Text(self.frame,bg='gray95')
200       self.text.place(relx=0.2,rely=0.2,relwidth=0.6,relheight=0.6)
201       but_val = Button(self.frame,text='Valider',command = self.valide_shell)
202       but_ann = Button(self.frame,text='Annuler',command = self.annule_shell)
203       but_val.place(relx=0.35,rely=0.9,anchor='center')
204       but_ann.place(relx=0.65,rely=0.9,anchor='center')
205       self.display_valeur()
206
207   def gen_aide(self):
208       """
209       Retourne une chaîne de caractères d'aide sur la valeur qu'attend l'objet
210       pointé par self
211       """
212       return "Un shell est attendu"
213     
214   def valide_shell(self,event=None):
215       """
216       Récupère la valeur saisie par l'utilisateur dans self.text
217       et la stocke dans l'objet MCSIMP courant
218       """
219       texte = self.text.get(1.0,END)
220       self.record_valeur(texte)
221
222   def annule_shell(self,event=None):
223       """
224       Annule toute saisie dans self.text
225       """
226       self.text.delete(0,END)
227
228   def display_valeur(self,val=None):
229       """
230       Affiche la valeur de l'objet pointé par self
231       """
232       if val != None :
233           valeur = val
234       else:
235           valeur = self.node.item.get_valeur()
236       if valeur == None  or valeur == '': return
237       self.text.insert(END,valeur)
238
239 class PLUSIEURS_Panel(newSIMPPanel):
240   """
241   Classe virtuelle servant de classe mère à toutes celles définissant
242   un panneau pour un mot-clé simple qui attend une liste de valeurs
243   """
244   def accepte_modifs_valeur(self,min,max):
245       """
246       Méthode qui récupère la liste des valeurs donnée par l'utilisateur
247       et l'affecte au mot-clé courant.
248       """
249       l1_valeurs = self.Liste_valeurs.get_liste()
250       l_valeurs=[]
251       for  val in l1_valeurs :
252         if val != '' and val != None :
253            l_valeurs.append(val)
254     
255       longueur = len(l_valeurs)
256       if longueur < min or longueur > max :
257           self.parent.appli.affiche_infos("Valeur refusée : nombre d'éléments incorrect dans la liste")
258           return
259       if longueur > 1:
260          valeur = tuple(l_valeurs)
261       elif longueur == 1:
262          valeur = l_valeurs[0]
263       else:
264          valeur = None
265
266       self.parent.appli.affiche_infos("Valeur acceptée")
267       self.record_valeur(valeur)
268       #if self.node.item.isvalid():
269       #    self.node.parent.select()
270       # fermeture de la fenêtre de sélection
271       if self.ajout_valeurs:
272           self.ajout_valeurs.quit()
273           
274   def annule_modifs_valeur(self):
275       """
276       RAZ de la liste des valeurs (annule toutes les valeurs saisies par l'utilisateur)
277       """
278       self.node.select()
279       # fermeture de la fenêtre de sélection
280       if self.ajout_valeurs:
281           self.ajout_valeurs.quit()
282           
283   def add_valeur_sans_into(self,name=None,encorevalide=1):
284       """
285       Lit ce que l'utilisateur a saisi dans self.entry et cherche à
286       l'évaluer :
287         - si la valeur est acceptable, elle est ajoutée dans la liste des valeurs
288         - sinon elle est refusée
289       encorevalide vaut 1 si le validateur trouve l item et la liste correctes
290                         0 si le validateur trouve la valeur de l item incorrecte
291                        -1 si le validateur trouve la liste incorrecte
292       """
293
294       commentaire="Valeur incorrecte : ajout à la liste refusé"
295       testvalide=1
296
297       # Lecture de la zone de saisie et evaluation si nécessaire
298       if name != None :
299          valeur = name
300       else:
301          valeurentree = self.get_valeur()
302          if valeurentree == '': valeur=None
303          valeurentree,testvalide=self.node.item.eval_valeur(valeur)
304          if (not testvalide) :
305             commentaire = "impossible d'évaluer : %s " %`valeurentree`
306
307       # Pas de traitement des valeurs nulles ( a priori clic involontaire
308       if (valeur == None or valeur =="") :
309           commentaire = "Pas de saisie des valeurs nulles"
310           encorevalide = -2 
311           testtype=0
312       else :
313           testtype = self.node.item.object.verif_type(valeur)
314           if not testtype :
315             commentaire ="Type de la valeur incorrecte"
316             encorevalide=-2
317                 
318       if (encorevalide ==0) :
319          commentaire=self.node.item.info_erreur_item()
320       if (encorevalide == -1) :
321          commentaire=self.node.item.info_erreur_liste()
322          # On traite le cas ou la liste n est pas valide pour un pb de cardinalite
323          min,max = self.node.item.GetMinMax()
324          if len(self.Liste_valeurs.get_liste()) >= max : 
325             commentaire="La liste a déjà atteint le nombre maximum d'éléments,ajout refusé"
326
327       if testvalide and (encorevalide == 1):
328          min,max = self.node.item.GetMinMax()
329
330          if testtype :
331             liste_valeurs = self.Liste_valeurs.get_liste()
332             if len(liste_valeurs) >= max :
333                 commentaire="La liste a déjà atteint le nombre maximum d'éléments,ajout refusé"
334             else :
335                liste_valeurs.append(valeur)
336                self.Liste_valeurs.put_liste(liste_valeurs)
337                self.erase_valeur()
338                commentaire="Nouvelle valeur acceptée"
339          else :
340             commentaire ="Type de la valeur incorrecte"
341
342       #self.erase_valeur()
343       self.parent.appli.affiche_infos(commentaire)
344
345   def sup_valeur_sans_into(self,name=None):
346       """
347       Méthode qui sert à retirer de la liste des valeurs la valeur sélectionnée
348       """
349       liste_valeurs = self.Liste_valeurs.get_liste()
350       try:
351           liste_valeurs.remove(self.selected_valeur)
352       except:
353           # la valeur sélectionnée n'est pas dans la liste
354           return
355       self.Liste_valeurs.put_liste(liste_valeurs)
356       self.display_valeur(self.selected_valeur)
357       self.selected_valeur = None      
358
359   def display_valeur(self,val=None):
360       """
361       Affiche la valeur passée en argument dans l'entry de saisie.
362       Par défaut affiche la valeur du mot-clé simple
363       """
364       if not val :
365           valeur = self.node.item.getval()
366       else:
367           valeur = val
368       self.entry.delete(0,END)
369       if not valeur : return
370       self.entry.insert(0,str(valeur))
371       
372             
373 class PLUSIEURS_INTO_Panel(PLUSIEURS_Panel):
374   """
375   Classe servant à définir le panneau permettant d'afficher et de saisir une
376   liste de valeurs à choisir parmi une liste discrètes de valeurs possibles
377   """
378   def makeValeurPage(self,page):
379       """
380       Génère la page de saisie de plusieurs valeurs parmi un ensemble discret
381       de possibles
382       """
383       self.ajout_valeurs = None
384       # On récupère la bulle d'aide du panneau, l'objet, min et max (cardinalité de la liste),
385       # la liste des choix et la liste des valeurs
386       aide = self.get_aide()
387       aide = justify_text(texte=aide)
388       bulle_aide=self.get_bulle_aide()
389       objet_mc = self.node.item.get_definition()
390       min,max = self.node.item.GetMinMax()
391       #l_choix=list(objet_mc.into)
392       l_valeurs = self.node.item.GetListeValeurs()
393       l_choix= self.node.item.get_liste_possible(l_valeurs)
394       # reinitialisation de l_valeurs
395       l_valeurs = self.node.item.GetListeValeurs()
396
397       # remplissage du panneau
398       self.frame_valeurs = Frame(page)
399       self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
400       self.frame_boutons_fleches = Frame(page)
401       self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
402       self.frame_choix = Frame(page)
403       self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
404       self.frame_boutons = Frame(page)
405       self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
406       self.frame_aide = Frame(page)
407       self.frame_aide.place(relx=0.1,rely=0.75,relwidth=0.9,relheight=0.1)
408       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
409                                  ("<Button-3>",self.deselectValeur),
410                                  ("<Double-Button-1>",self.sup_valeur))
411       liste_commandes_choix = (("<Button-1>",self.selectChoix),
412                                ("<Button-3>",self.deselectChoix),
413                                ("<Double-Button-1>",self.add_choix))
414       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,
415                                       l_valeurs,liste_commandes = liste_commandes_valeurs,
416                                       titre="Valeur(s) actuelle(s)")
417       self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,
418                                     liste_commandes = liste_commandes_choix,
419                                     titre= "Valeurs possibles")
420       bouton_add = Button(self.frame_boutons_fleches,
421                           #text="<--",
422                           image = images.get_image('arrow_left'),
423                           command = self.add_choix)
424       bouton_sup = Button(self.frame_boutons_fleches,
425                           #text="-->",
426                           image = images.get_image('arrow_right'),
427                           command = self.sup_valeur)
428       bouton_accepter = Button(self.frame_boutons,
429                                text='Valider',
430                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
431       bouton_annuler = Button(self.frame_boutons,
432                               text = 'Annuler',
433                               command = self.annule_modifs_valeur)
434       bouton_add.place(relx=0.3,rely=0.35)
435       bouton_sup.place(relx=0.3,rely=0.65)
436       for but in (bouton_accepter,bouton_annuler):
437           but.pack(side='left',padx=5)
438       self.Liste_valeurs.affiche_liste()
439       self.Liste_choix.affiche_liste()
440       for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
441           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
442           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
443       self.frame_aide.update()
444       self.aide = Label(self.frame_aide,
445                         text = aide,
446                         justify='center',
447                         anchor='center',
448                         wraplength=int(self.frame_aide.winfo_width()*0.8))
449       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
450
451   def get_aide(self):
452       """
453       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
454       que saisit l'utilisateur
455       """
456       commentaire=""
457       mc = self.node.item.get_definition()
458       d_aides = { 'TXM' : 'chaînes de caractères',
459                   'R'   : 'réels',
460                   'I'   : 'entiers',
461                   'C'   : 'complexes'}
462       type = mc.type[0]
463       if not d_aides.has_key(type) : 
464          if mc.min == mc.max:
465             return str(mc.min)+" valeur(s) est(sont) attendue(s)"
466          else :
467             return "entrez entre "+str(mc.min)+" et "+str(mc.max)+" valeurs"
468       if mc.min == mc.max:
469             commentaire="Une liste de "+str(mc.min)+" "+d_aides[type]+" est attendue"
470       else :
471             commentaire="Entre "+str(mc.min)+" et "+str(mc.max)+" valeurs de type  "+d_aides[type]+" sont attendues"
472       aideval=self.node.item.aide()
473       commentaire=commentaire + "\n" + aideval
474       return commentaire
475
476   def get_bulle_aide(self):
477       """
478       Retourne la bulle d'aide du panneau (affichée par clic droit)
479       """
480       return """Un clic sur une valeur des deux listes la sélectionne.
481       - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
482       dans la liste des valeurs que vous voulez affecter au mot-clé simple
483       - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
484       sélectionnée (elle apparaît alors à nouveau comme choix possible
485       dans la liste des choix à droite)
486       - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
487       au mot-clé simple courant
488       - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
489       avant toute modification depuis le dernier 'Valider'"""
490
491 class PLUSIEURS_BASE_Panel(PLUSIEURS_Panel):
492   """
493   Classe définissant le panel associé aux mots-clés qui demandent
494   à l'utilisateur de donner une liste de valeurs qui ne sont pas
495   à choisir dans une liste discrètes et qui sont de type de base :
496   entier, réel, string,...
497   """
498   def makeValeurPage(self,page):
499       """
500       Crée la page de saisie d'une liste de valeurs à priori quelconques,
501       cad qui ne sont  pas à choisir dans une liste prédéfinie
502       """
503       # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
504       # et la liste des valeurs déjà affectées à l'objet courant
505       bulle_aide=self.get_bulle_aide()
506       objet_mc = self.node.item.get_definition()
507       aide = self.get_aide()
508       aide = justify_text(texte=aide)
509       min,max = self.node.item.GetMinMax()
510       l_valeurs = self.node.item.GetListeValeurs()
511
512       # création des frames globales
513       self.frame1 = Frame(page,relief='groove',bd=2)
514       self.frame2 = Frame(page)
515       self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.85)
516       self.frame2.place(relx=0.,rely=0.85,relwidth=1,relheight=0.15)
517       self.frame_right = Frame(self.frame1)
518       self.frame_right.place(relx=0.35,rely=0.,relwidth=0.65,relheight=1.)
519
520       # création des frames internes
521       self.frame_valeurs = Frame(self.frame1)
522       self.frame_valeurs.place(relx=0.02,rely=0.05,relwidth=0.35,relheight=0.95)
523       self.frame_boutons_fleches = Frame(self.frame_right)
524       self.frame_boutons_fleches.place(relx=0.,rely=0.2,relwidth=0.2,relheight=0.5)
525       self.frame_choix = Frame(self.frame_right)
526       self.frame_choix.place(relx=0.2,rely=0.2,relwidth=0.7,relheight=0.5)
527       self.frame_aide = Frame(self.frame_right)
528       self.frame_aide.place(relx=0.1,rely=0.7,relwidth=0.8,relheight=0.3)
529       self.frame_boutons = Frame(self.frame2)
530       self.frame_boutons.place(relx=0.35,rely=0.,relwidth=0.3,relheight=1.)
531       for fram in (self.frame1,self.frame2,self.frame_right,self.frame_valeurs,
532                  self.frame_boutons_fleches,self.frame_choix,self.frame_aide,self.frame_boutons):
533           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
534           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
535
536       # création des objets dans les frames
537       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
538                                  ("<Button-3>",self.deselectValeur),
539                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
540       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
541                                       titre="Valeur(s) actuelle(s)")
542
543       # Création de l'entry ou de la liste des SD
544       self.label = Label(self.frame_choix,text="Valeur :")
545       # PN : pour ajouter les validators
546       self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base)
547       self.label.place(relx=0.05,rely=0.5)
548
549       # Création d'un bouton "Importer ..." sur le panel.
550       bouton_valeurs_fichier = Button(self.frame_choix,
551                                       text="Importer ...",
552                                       command=self.select_in_file)
553       bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)
554       self.ajout_valeurs = None
555
556       # boutons Ajouter et Supprimer
557       bouton_add = Button(self.frame_boutons_fleches,
558                           image = images.get_image('arrow_left'),
559                           command = self.add_valeur_plusieurs_base)
560       bouton_sup = Button(self.frame_boutons_fleches,
561                           image = images.get_image('arrow_right'),
562                           command = self.sup_valeur_sans_into)
563       bouton_add.place(relx=0.3,rely=0.35)
564       bouton_sup.place(relx=0.3,rely=0.65)
565       # affichage de l'aide
566       self.frame_aide.update()
567       self.aide = Label(self.frame_aide,
568                         text = aide,
569                         justify='center',
570                         anchor='center',
571                         wraplength=int(self.frame_aide.winfo_width()*0.8))
572       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
573       self.Liste_valeurs.affiche_liste()
574       # boutons Accepter et Annuler
575       bouton_accepter = Button(self.frame_boutons,
576                                text='Valider',
577                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
578       bouton_annuler = Button(self.frame_boutons,
579                               text = 'Annuler',
580                               command = self.annule_modifs_valeur)
581       for but in (bouton_accepter,bouton_annuler):
582           but.pack(side='left',padx=5)
583
584   def add_valeur_plusieurs_base(self,name=None):
585       if name != None :
586          valeur = name
587       else:
588          valeurentree = self.get_valeur()
589          if valeurentree == '': valeur=None
590          valeur,validite=self.node.item.eval_valeur(valeurentree)
591          if not validite :
592             commentaire = "impossible d'évaluer : %s " %`valeurentree`
593             self.parent.appli.affiche_infos(commentaire)
594             return
595
596       encorevalide=self.node.item.valide_item(valeur)
597       if encorevalide :
598          listecourante=self.Liste_valeurs.get_liste()
599          encorevalide=self.node.item.valide_liste_partielle(valeur,listecourante)
600          if not encorevalide : encorevalide = -1
601       self.add_valeur_sans_into(valeur,encorevalide)
602     
603   def select_in_file(self):
604       """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
605       nom_fichier = askopenfilename(title="Choix fichier :")
606       if nom_fichier == "":
607           return
608       try:
609           f = open(nom_fichier, "rb")
610           selection_texte = f.read()
611           f.close()
612           self.ajout_valeurs = FenetreDeSelection(self, 
613                                                   self.node.item,
614                                                   self.parent.appli,
615                                                   titre="Sélection de valeurs",
616                                                   texte=selection_texte)
617       except:
618           traceback.print_exc()
619           showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
620           
621   def get_bulle_aide(self):
622       """
623       Retourne l'aide associée au panneau courant
624       """
625       return """Taper dans la boîte de saisie de droite la valeur que
626       vous voulez affecter au mot-clé simple.
627       - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
628       dans la liste des valeurs que vous voulez affecter au mot-clé simple
629       - Un clic sur une valeur de la liste la sélectionne
630       - Un clic sur la flèche droite ou un double-clic retire la valeur
631       sélectionnée de la liste
632       - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
633       au mot-clé simple
634       - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
635       depuis le dernier clic sur 'Valider'"""
636
637   def get_aide(self):
638       """
639       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
640       que saisit l'utilisateur
641       """
642       commentaire=""
643       mc = self.node.item.get_definition()
644       d_aides = { 'TXM' : 'chaînes de caractères',
645                   'R'   : 'réels',
646                   'I'   : 'entiers',
647                   'C'   : 'complexes'}
648       type = mc.type[0]
649       if not d_aides.has_key(type) : return 'Type de base inconnu'
650       if mc.min == mc.max:
651           commentaire="Une liste de "+d_aides[type]+" chaînes de caractères est attendue"
652       else :
653           commentaire="Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
654       aideval=self.node.item.aide()
655       commentaire=commentaire +"\n"+aideval
656       return commentaire
657
658   def make_entry(self,frame,command):
659       """
660       Crée l'entry de saisie de la valeur souhaitée : distingue le
661       cas d'un complexe attendu, d'une autre valeur quelconque
662       """
663       if self.node.item.wait_complex():
664           self.typ_cplx=StringVar()
665           self.typ_cplx.set('RI')
666           rb1 = Radiobutton(frame, text='RI',variable=self.typ_cplx,value='RI')
667           rb2 = Radiobutton(frame, text='MP',variable=self.typ_cplx,value='MP')
668           self.entry1 = Pmw.EntryField(frame,validate='real')
669           self.entry2 = Pmw.EntryField(frame,validate='real')
670           rb1.place(relx=0.05,rely = 0.4)
671           rb2.place(relx=0.05,rely = 0.6)
672           self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus)
673           self.entry2.component('entry').bind("<Return>",lambda e,c=command:c())
674           self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
675           self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
676           self.entry1.focus()
677       else:
678           self.entry = Entry(frame,relief='sunken')
679           self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
680           self.entry.bind("<Return>",lambda e,c=command:c())
681           self.entry.focus()
682
683   def get_valeur(self):
684       """
685       Retourne la valeur saisie par l'utilisateur dans self.entry
686       """
687       return self.entry.get()
688
689   def erase_valeur(self):
690       """
691       Efface la valeur donnée par l'utilisateur dans l'entry
692       """
693       self.entry.delete(0,END)
694         
695 class PLUSIEURS_ASSD_Panel(PLUSIEURS_Panel):
696   """
697   Classe définissant le panel associé aux mots-clés qui demandent
698   à l'utilisateur de donner une liste de valeurs qui ne sont pas
699   à choisir dans une liste discrètes et qui sont de type dérivé d'ASSD
700   """
701   def makeValeurPage(self,page):
702       """
703       Génère la page de saisie de plusieurs noms de SD parmi un ensemble discret
704       de SD possibles, cad d'un type cohérent avec les types attendus par le mot-clé simple
705       """
706       # On récupère la bulle d'aide du panneau, l'objet, l'aide, min et max (cardinalité de la liste),
707       # la liste des valeurs déjà affectées à l'objet courant et la liste des SD du bon type
708       bulle_aide=self.get_bulle_aide()
709       self.ajout_valeurs=None
710       objet_mc = self.node.item.get_definition()
711       aide = self.get_aide()
712       aide = justify_text(texte=aide)
713       min,max = self.node.item.GetMinMax()
714       l_valeurs = self.node.item.GetListeValeurs()
715       l_choix=self.node.item.get_sd_avant_du_bon_type()
716       l_choix.sort()
717       # remplissage du panneau
718       self.frame_valeurs = Frame(page)
719       self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
720       self.frame_boutons_fleches = Frame(page)
721       self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
722       self.frame_choix = Frame(page)
723       self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
724       self.frame_boutons = Frame(page)
725       self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
726       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
727                                  ("<Button-3>",self.deselectValeur),
728                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
729       liste_commandes_choix = (("<Button-1>",self.selectChoix),
730                                ("<Button-3>",self.deselectChoix),
731       #                         ("<Double-Button-1>",self.add_valeur_sans_into))
732                                ("<Double-Button-1>",self.add_eval_valeur_sans_into))
733       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
734                                       titre="Valeur(s) actuelle(s)")
735       self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
736                                     titre= "Valeurs possibles")
737       bouton_add = Button(self.frame_boutons_fleches,
738                           #text="<--",
739                           image = images.get_image('arrow_left'),
740       #                    command = self.add_valeur_sans_into)
741                           command = self.add_eval_valeur_sans_into)
742       bouton_sup = Button(self.frame_boutons_fleches,
743                           #text="-->",
744                           image = images.get_image('arrow_right'),
745                           command = self.sup_valeur_sans_into)
746       bouton_accepter = Button(self.frame_boutons,
747                                text='Valider',
748                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
749       bouton_annuler = Button(self.frame_boutons,
750                               text = 'Annuler',
751                               command = self.annule_modifs_valeur)
752       bouton_add.place(relx=0.3,rely=0.35)
753       bouton_sup.place(relx=0.3,rely=0.65)
754       for but in (bouton_accepter,bouton_annuler):
755           but.pack(side='left',padx=5)
756       self.Liste_valeurs.affiche_liste()
757       self.Liste_choix.affiche_liste()
758       for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
759           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
760           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
761   
762   def add_eval_valeur_sans_into(self,valeurentree=None):
763       valeur,validite=self.node.item.eval_valeur(valeurentree)
764       if not validite :
765              commentaire = "impossible d'évaluer : %s " %`valeurentree`
766              self.parent.appli.affiche_infos(commentaire)
767              return
768       self.add_valeur_sans_into(valeur)
769
770   def get_bulle_aide(self):
771       """
772       Retourne la bulle d'aide associée au panneau
773       """
774       return """Un clic sur une valeur des deux listes la sélectionne.
775       - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
776       dans la liste des valeurs que vous voulez affecter au mot-clé simple
777       - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
778       sélectionnée (elle apparaît alors à nouveau comme choix possible
779       dans la liste des choix à droite)
780       - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
781       au mot-clé simple courant
782       - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
783       avant toute modification depuis le dernier 'Valider'"""
784
785   def get_aide(self):
786       """
787       Retourne la phrase d'aide indiquant de quel type doivent être les
788       valeurs que doit entrer l'utilisateur
789       """
790       commentaire=""
791       mc = self.node.item.get_definition()
792       type = mc.type[0].__name__  
793       if len(mc.type)>1 :
794           for typ in mc.type[1:] :
795               type = type + ' ou '+typ.__name__
796       if mc.min == mc.max:
797         commentaire="Une liste de "+`mc.min`+" objets de type "+type+" est attendue"
798       else :
799         commentaire="Une liste d'objets de type "+type+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
800       aideval=self.node.item.aide()
801       commentaire=commentaire +"\n"+ aideval
802       return commentaire
803
804     
805   def sup_valeur(self,name=None):
806       """
807       Supprime la valeur selectionnée de la liste des valeurs et la rajoute
808       à la liste des choix possibles
809       """
810       liste_valeurs = self.Liste_valeurs.get_liste()
811       liste_valeurs.remove(self.selected_valeur)
812       liste_choix = self.node.item.get_definition().into
813       liste_choix = substract_list(liste_choix,liste_valeurs)
814       self.Liste_valeurs.put_liste(liste_valeurs)
815       self.Liste_choix.put_liste(liste_choix)
816       self.selected_valeur = None      
817     
818   def erase_valeur(self):
819       pass
820
821   def get_valeur(self):
822       """
823       Retourne la valeur sélectionnée dans la liste des choix
824       """
825       return self.selected_choix
826
827   def display_valeur(self,val=None):
828       """
829          Affiche la valeur passée en argument dans l'entry de saisie.
830          Par défaut affiche la valeur du mot-clé simple
831       """
832       # Il n'y a pas d'entry pour ce type de panneau
833       return
834
835     
836 class UNIQUE_Panel(newSIMPPanel):
837   """
838   Classe virtuelle servant de classe mère à toutes celles définissant un panneau
839   permettant l'affichage et la saisie d'une valeur unique pour le mot-clé simple
840   """
841
842   def erase_valeur(self):
843       """
844       Efface l'entry de saisie
845       """
846       self.entry.delete(0,END)
847
848   def get_valeur(self):
849       """
850       Retourne la valeur donnée par l'utilisateur
851       """
852       return self.entry.get()
853     
854   def valid_valeur(self):
855       """
856       Teste si la valeur fournie par l'utilisateur est une valeur permise :
857       - si oui, l'enregistre
858       - si non, restaure l'ancienne valeur
859       """
860       if self.parent.modified == 'n' : self.parent.init_modif()
861       anc_val = self.node.item.get_valeur()
862       valeurentree = self.get_valeur()
863       self.erase_valeur()
864       valeur,validite=self.node.item.eval_valeur(valeurentree)
865       if not validite :
866              commentaire = "impossible d'évaluer : %s " %`valeurentree`
867              self.parent.appli.affiche_infos(commentaire)
868              return
869    
870       test = self.node.item.set_valeur(valeur)
871        
872       if not test :
873           mess = "impossible d'évaluer : %s " %`valeur`
874           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée : "+mess)
875       elif self.node.item.isvalid() :
876           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
877           if self.node.item.get_position()=='global':
878               self.node.etape.verif_all()
879           elif self.node.item.get_position()=='global_jdc':
880               self.node.racine.verif_all()
881           else :
882               self.node.parent.verif()
883           self.node.update()
884           self.node.parent.select()
885       else :
886           cr = self.node.item.get_cr()
887           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
888           self.reset_old_valeur(anc_val,mess=mess)
889
890 class UNIQUE_INTO_Panel(UNIQUE_Panel):
891   """
892   Classe définissant le panel associé aux mots-clés qui demandent
893   à l'utilisateur de choisir une seule valeur parmi une liste de valeurs
894   discrètes
895   """
896   def makeValeurPage(self,page):
897       """
898       Génère la page de saisie d'une seule valeur parmi un ensemble
899       discret de possibles
900       """
901       # récupération de la bulle d'aide et de l'objet mc
902       bulle_aide=self.get_bulle_aide()
903       objet_mc = self.node.item.get_definition()
904       # remplissage du panel
905       self.frame_valeur = Frame(page)
906       self.frame_valeur.pack(fill='both',expand=1)
907       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : 
908                               s.parent.appli.affiche_aide(e,a))
909       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
910       #l_choix=list(objet_mc.into)
911       #l_choix.sort()
912       l_choix=self.node.item.get_liste_possible([])
913       self.label = Label(self.frame_valeur,text='Choisir une valeur :')
914       self.label.pack(side='top')
915       self.frame = Frame(page)
916       self.frame.place(relx=0.33,rely=0.2,relwidth=0.33,relheight=0.6)
917       liste_commandes = (("<Button-1>",self.selectChoix),
918                          ("<Button-3>",self.deselectChoix),
919                          ("<Double-Button-1>",self.record_valeur))
920       self.Liste_choix = ListeChoix(self,self.frame,l_choix,
921                                     liste_commandes = liste_commandes,
922                                     titre="Valeurs possibles")
923       self.Liste_choix.affiche_liste()
924
925   def get_bulle_aide(self):
926       """
927       Retourne la bulle d'aide affectée au panneau courant (affichée par clic droit)
928       """
929       return """Double-cliquez sur la valeur désirée
930       pour valoriser le mot-clé simple courant"""
931
932 class UNIQUE_ASSD_Panel(UNIQUE_Panel):
933   """
934   Classe servant à définir le panneau associé aux objets qui attendent une valeur unique
935   d'un type dérivé d'ASSD
936   """
937   def valid_valeur_automatique(self):
938       """
939          Réalise la validation d'un concept sans remonter dans le
940          node parent dans le cas ou il n'y a qu'un concept possible (liste de longueur 1)
941          Identique à valid_valeur moins appel de self.node.parent.select()
942          On pourrait supposer que le seul concept présent est valide et donc ne pas
943          réaliser tous les tests de vérification.
944       """
945       if self.parent.modified == 'n' : self.parent.init_modif()
946       valeur = self.get_valeur()
947       self.erase_valeur()
948       anc_val = self.node.item.get_valeur()
949       valeur,validite=self.node.item.eval_valeur_item(valeur)
950       test = self.node.item.set_valeur(valeur)
951       print self.node.item.isvalid()
952       if not test :
953           mess = "impossible d'évaluer : %s " %`valeur`
954           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
955       elif self.node.item.isvalid() :
956           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
957           if self.node.item.get_position()=='global':
958               self.node.etape.verif_all()
959           elif self.node.item.get_position()=='global_jdc':
960               self.node.racine.verif_all()
961           else :
962               self.node.parent.verif()
963           self.node.update()
964       else :
965           cr = self.node.item.get_cr()
966           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
967           self.reset_old_valeur(anc_val,mess=mess)
968
969   def makeValeurPage(self,page):
970       """
971           Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une 
972           SD de type dérivé d'ASSD
973       """
974       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
975       # et de la liste des SD du bon type (constituant la liste des choix)
976       bulle_aide=self.get_bulle_aide()
977       aide=self.get_aide()
978       aide= justify_text(texte=aide)
979       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
980       # Remplissage du panneau
981       self.valeur_choisie = StringVar()
982       self.valeur_choisie.set('')
983       min,max =  self.node.item.GetMinMax()
984       if (min == 1 and min == max and len(liste_noms_sd)==1):
985           if self.valeur_choisie.get() != liste_noms_sd[0]:
986              self.valeur_choisie.set(liste_noms_sd[0])
987              self.valid_valeur_automatique()
988          
989       self.frame_valeur = Frame(page)
990       self.frame_valeur.pack(fill='both',expand=1)
991       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
992       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
993       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
994                                          items=liste_noms_sd,
995                                          labelpos='n',
996                                          label_text="Structures de données du type\n requis par l'objet courant :",
997                                          listbox_height = 6,
998                                          selectioncommand=self.select_valeur_from_list,
999                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
1000       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
1001       Label(self.frame_valeur,text='Structure de donnée choisie :').place(relx=0.05,rely=0.6)
1002       #self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
1003       Label(self.frame_valeur,textvariable=self.valeur_choisie).place(relx=0.5,rely=0.6)
1004       # affichage de la valeur courante
1005       self.display_valeur()
1006
1007   def get_bulle_aide(self):
1008       """
1009       Retourne l'aide associée au panneau
1010       """
1011       return "Double-cliquez sur la structure de donnée désirée pour valoriser le mot-clé simple courant"
1012
1013   def get_aide(self):
1014       """
1015       Retourne la phrase d'aide indiquant de quel type doit être la valeur à donner par l'utilisateur
1016       """
1017       mc = self.node.item.get_definition()
1018       type = mc.type[0].__name__  
1019       if len(mc.type)>1 :
1020           for typ in mc.type[1:] :
1021               type = type + ' ou '+typ.__name__
1022       commentaire="Un objet de type "+type+" est attendu"
1023       aideval=self.node.item.aide()
1024       commentaire=commentaire +"\n"+ aideval
1025       return commentaire
1026
1027     
1028   def select_valeur_from_list(self):
1029       """
1030       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
1031       """
1032       if len(self.listbox.get()) == 0 : return
1033       choix = self.listbox.getcurselection()[0]
1034       self.valeur_choisie.set(choix)
1035
1036   def choose_valeur_from_list(self,command):
1037       """
1038       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
1039       Exécute command
1040       """
1041       if len(self.listbox.get()) == 0 : return
1042       choix = self.listbox.getcurselection()[0]
1043       self.valeur_choisie.set(choix)
1044       apply(command,(),{})
1045
1046   def get_valeur(self):
1047       """
1048       Retourne la valeur donnée par l'utilisateur au MCS
1049       """
1050       return self.valeur_choisie.get()
1051     
1052   def display_valeur(self):
1053       """
1054       Affiche la valeur de l'objet pointé par self
1055       """
1056       valeur = self.node.item.get_valeur()
1057       if valeur == None or valeur == '' : return # pas de valeur à afficher ...
1058       self.valeur_choisie.set(valeur.nom)
1059
1060   def erase_valeur(self):
1061       pass
1062
1063 class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel):
1064   """
1065   Classe servant à définir le panneau correspondant à un mot-clé simple
1066   qui attend une valeur unique de type dérivé d'ASSD ou non encore
1067   existante (type CO(...) utilisé dans les macros uniquement)
1068   """
1069   def makeValeurPage(self,page):
1070       """
1071       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une SD de type dérivé
1072       d'ASSD
1073       """
1074       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
1075       # et de la liste des SD du bon type (constituant la liste des choix)
1076       bulle_aide=self.get_bulle_aide()
1077       aide=self.get_aide()
1078       aide= justify_text(texte=aide)
1079       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
1080       # Remplissage du panneau
1081       self.frame_valeur = Frame(page)
1082       self.frame_valeur.pack(fill='both',expand=1)
1083       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1084       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1085       # affichage de la liste des SD existantes et du bon type
1086       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
1087                                          items=liste_noms_sd,
1088                                          labelpos='n',
1089                                          label_text="Structures de données du type\n requis par l'objet courant :",
1090                                          listbox_height = 6,
1091                                          selectioncommand=self.select_valeur_from_list,
1092                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
1093       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
1094       # affichage du bouton 'Nouveau concept'
1095       self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ",
1096                                  items = ('NON','OUI'),menubutton_width=10)
1097       self.b_co.configure(command = lambda e,s=self : s.ask_new_concept())
1098       self.b_co.place(relx=0.05,rely=0.6,anchor='w')
1099       self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :')
1100       self.entry_co = Entry(self.frame_valeur)
1101       self.entry_co.bind('<Return>',self.valid_nom_concept_co)
1102       # affichage du label de la structure de donnée choisie
1103       self.l_resu = Label(self.frame_valeur,text='Structure de donnée choisie :')
1104       self.valeur_choisie = StringVar()
1105       self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
1106       self.frame_valeur.update()
1107       self.aide = Label(self.frame_valeur,
1108                         text = aide,
1109                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1110                         justify='center')
1111       self.aide.place(relx=0.5,rely=0.85,anchor='n')
1112       # affichage de la valeur courante
1113       self.display_valeur()
1114       
1115   def get_bulle_aide(self):
1116       """
1117       Retourne la bulle d'aide du panneau
1118       """
1119       return """Double-cliquez sur la structure de donnée désirée
1120       pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour
1121       entrer le nom d'un concept non encore existant"""
1122
1123   def valid_valeur(self):
1124       """
1125       Teste si la valeur fournie par l'utilisateur est une valeur permise :
1126       - si oui, l'enregistre
1127       - si non, restaure l'ancienne valeur
1128       """
1129       if self.parent.modified == 'n' : self.parent.init_modif()
1130       valeur = self.get_valeur()
1131       self.erase_valeur()
1132       anc_val = self.node.item.get_valeur()
1133       test_CO=self.node.item.is_CO(anc_val)
1134       test = self.node.item.set_valeur(valeur)
1135       if not test :
1136           mess = "impossible d'évaluer : %s " %`valeur`
1137           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
1138           return
1139       elif self.node.item.isvalid() :
1140           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
1141           if test_CO:
1142              # il faut egalement propager la destruction de l'ancien concept
1143              self.node.item.delete_valeur_co(valeur=anc_val)
1144              # et on force le recalcul des concepts de sortie de l'etape
1145              self.node.item.object.etape.get_type_produit(force=1)
1146              # et le recalcul du contexte
1147              self.node.item.object.etape.parent.reset_context()
1148           self.node.parent.select()
1149       else :
1150           cr = self.node.item.get_cr()
1151           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
1152           self.reset_old_valeur(anc_val,mess=mess)
1153           return
1154       if self.node.item.get_position()=='global':
1155           self.node.etape.verif_all()
1156       elif self.node.item.get_position()=='global_jdc':
1157           self.node.racine.verif_all()
1158       else :
1159           self.node.parent.verif()
1160       self.node.update()
1161
1162   def valid_nom_concept_co(self,event=None):
1163       """
1164       Lit le nom donné par l'utilisateur au concept de type CO qui doit être
1165       la valeur du MCS courant et stocke cette valeur
1166       """
1167       if self.parent.modified == 'n' : self.parent.init_modif()
1168       anc_val = self.node.item.get_valeur()
1169       nom_concept = self.entry_co.get()
1170       test,mess=self.node.item.set_valeur_co(nom_concept)
1171       if not test:
1172           # On n'a pas pu créer le concept
1173           self.parent.appli.affiche_infos(mess)
1174           return
1175       elif self.node.item.isvalid() :
1176           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
1177           self.node.parent.select()
1178       else :
1179           cr = self.node.item.get_cr()
1180           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
1181           self.reset_old_valeur(anc_val,mess=mess)
1182           return
1183       if self.node.item.get_position()=='global':
1184           self.node.etape.verif_all()
1185       elif self.node.item.get_position()=='global_jdc':
1186           self.node.racine.verif_all()
1187       else :
1188           self.node.parent.verif()
1189       if self.node.item.isvalid():
1190           self.node.parent.select()
1191       self.node.update()
1192
1193   def ask_new_concept(self):
1194       """
1195       Crée une entry dans le panneau d'un MCS qui attend un concept OU un CO() afin de
1196       permettre à l'utilisateur de donner le nom du nouveau concept
1197       """
1198       new_concept = self.b_co.getcurselection()
1199       if new_concept == 'OUI':
1200           self.label_co.place(relx=0.05,rely=0.7)
1201           self.entry_co.place(relx=0.45,rely=0.7,relwidth=0.25)
1202           self.l_resu.place_forget()
1203           self.label_valeur.place_forget()
1204           self.entry_co.focus()
1205       elif new_concept == 'NON':
1206           # On est passe de OUI à NON, on supprime la valeur
1207 # PN correction de bug (on passe de non a non et cela supprime la valeur)
1208 # ajout du if de le ligne suivane
1209           if self.node.item.is_CO():
1210                 self.node.item.delete_valeur_co()
1211                 self.record_valeur(name=None,mess="Suppression CO enregistrée")
1212                 self.label_co.place_forget()
1213                 self.entry_co.place_forget()
1214                 self.l_resu.place(relx=0.05,rely=0.7)
1215                 self.label_valeur.place(relx=0.45,rely=0.7)
1216           
1217   def display_valeur(self):
1218       """
1219       Affiche la valeur de l'objet pointé par self
1220       """
1221       valeur = self.node.item.get_valeur()
1222       if valeur == None or valeur == '': 
1223          self.valeur_choisie.set('')
1224          return # pas de valeur à afficher ...
1225       # il faut configurer le bouton si la valeur est un objet CO
1226       # sinon afficher le nom du concept dans self.valeur_choisie
1227       if self.node.item.is_CO():
1228           self.b_co.invoke('OUI')
1229           self.entry_co.insert(0,valeur.nom)
1230       else:
1231           self.valeur_choisie.set(valeur.nom)
1232
1233   def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
1234       """
1235       Enregistre  val comme valeur de self.node.item.object SANS faire de test de validité
1236       """
1237       if self.parent.modified == 'n' : self.parent.init_modif()
1238       if name != None:
1239           valeur =name
1240       else :
1241           self.entry_co.delete(0,END)
1242           valeur= self.entry_co.get()
1243       self.node.item.set_valeur_co(valeur)
1244       self.parent.appli.affiche_infos(mess)
1245       # On met a jour le display dans le panneau
1246       self.display_valeur()
1247       if self.node.item.get_position()=='global':
1248           self.node.etape.verif_all()
1249       elif self.node.item.get_position()=='global_jdc':
1250           self.node.racine.verif_all()
1251       else :
1252           self.node.parent.verif()
1253       if self.node.item.isvalid():
1254           self.node.parent.select()
1255       self.node.update()
1256
1257
1258 class UNIQUE_BASE_Panel(UNIQUE_Panel):
1259   """
1260   Classe servant à définir le panneau associé aux mots-clés simples qui attendent
1261   une valeur d'un type de base (entier, réel ou string).
1262   """
1263   def makeValeurPage(self,page):
1264       """
1265       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1266       de base cad entier, réel, string ou complexe
1267       """
1268       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
1269       # et de la liste des SD du bon type (constituant la liste des choix)
1270       bulle_aide=self.get_bulle_aide()
1271       aide=self.get_aide()
1272       aide= justify_text(texte=aide)
1273       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
1274       # Remplissage du panneau
1275       self.frame_valeur = Frame(page)
1276       self.frame_valeur.pack(fill='both',expand=1)
1277       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1278       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1279       self.label = Label(self.frame_valeur,text='Valeur :')
1280       self.label.place(relx=0.1,rely=0.5)
1281       self.entry = Entry(self.frame_valeur,relief='sunken')
1282       self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
1283       self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
1284       self.entry.focus()
1285       # aide associée au panneau
1286       self.frame_valeur.update()
1287       self.aide = Label(self.frame_valeur, 
1288                         text = aide,
1289                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1290                         justify='center')
1291       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1292       # affichage de la valeur du MCS
1293       self.display_valeur()
1294
1295   def get_aide(self):
1296       """
1297       Retourne la phrase d'aide indiquant de quel type doit être la valeur
1298       du mot-clé simple fournie par l'utilisateur
1299       """
1300       mc = self.node.item.get_definition()
1301       d_aides = { 'TXM' : "Une chaîne de caractères est attendue",
1302                   'R'   : "Un réel est attendu",
1303                   'I'   : "Un entier est attendu"}
1304       type = mc.type[0]
1305       commentaire=d_aides.get(type,"Type de base inconnu")
1306       aideval=self.node.item.aide()
1307       commentaire=commentaire +"\n"+ aideval
1308       return commentaire
1309
1310   def get_bulle_aide(self):
1311       """
1312       Retourne la bulle d'aide associée au panneau et affichée par clic droit
1313       """
1314       return """Saisissez la valeur que vous voulez affecter au mot-clé simple
1315       dans la zone de saisie et pressez <Return>"""
1316       
1317   def display_valeur(self):
1318       """
1319       Affiche la valeur de l'objet pointé par self
1320       """
1321       valeur = self.node.item.get_valeur()
1322       if valeur == None or valeur == '' : return # pas de valeur à afficher ...
1323       self.entry.delete(0,END)
1324       self.entry.insert(0,valeur)
1325       self.entry.focus()
1326       
1327 class UNIQUE_COMP_Panel(UNIQUE_Panel):
1328   """
1329   Classe servant à définir le panneau associé aux mots-clés simples
1330   qui attendent une valeur de type complexe
1331   """
1332   def makeValeurPage(self,page):
1333       """
1334       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1335       de base cad entier, réel, string ou complexe
1336       """
1337       # Récupération de l'aide associée au panneau et de l'aide destinée à l'utilisateur
1338       bulle_aide=self.get_bulle_aide()
1339       aide=self.get_aide()
1340       aide= justify_text(texte=aide)
1341       # Remplissage du panneau
1342       self.frame_valeur = Frame(page)
1343       self.frame_valeur.pack(fill='both',expand=1)
1344       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1345       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1346       self.label = Label(self.frame_valeur,text='Valeur :')
1347       self.label.place(relx=0.1,rely=0.5)
1348       self.typ_cplx=StringVar()
1349       self.typ_cplx.set('RI')
1350       rb1 = Radiobutton(self.frame_valeur, text='RI',variable=self.typ_cplx,value='RI')
1351       rb2 = Radiobutton(self.frame_valeur, text='MP',variable=self.typ_cplx,value='MP')
1352       self.entry1 = Pmw.EntryField(self.frame_valeur,validate='real')
1353       self.entry2 = Pmw.EntryField(self.frame_valeur,validate='real')
1354       rb1.place(relx=0.05,rely = 0.4)
1355       rb2.place(relx=0.05,rely = 0.6)
1356       self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus())
1357       self.entry2.component('entry').bind("<Return>",lambda e,c=self.valid_valeur:c())
1358       self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
1359       self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
1360       self.entry1.focus()
1361       self.frame_valeur.update()
1362       self.aide = Label(self.frame_valeur,
1363                         text = aide,
1364                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1365                         justify='center')
1366       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1367
1368   def get_bulle_aide(self):
1369       """
1370       Retourne la bulle d'aide du panneau
1371       """
1372       return """-Choisissez votre format de saisie du complexe :
1373       \t 'RI' = parties réelle et imaginaire
1374       \t 'MP' = module/phase (en degrés)
1375       - Saisissez ensuite dans les deux zones de saisie les deux nombres attendus"""
1376
1377   def get_aide(self):
1378       """
1379       Retourne la phrase d'aide décrivant le type de la valeur que peut prendre
1380       le mot-clé simple courant
1381       """
1382       commentaire='Un complexe est attendu'
1383       aideval=self.node.item.aide()
1384       commentaire=commentaire +"\n"+ aideval
1385       return commentaire
1386
1387   def get_valeur(self):
1388       """
1389       Retourne le complexe saisi par l'utilisateur
1390       """
1391       l=[]
1392       l.append(self.typ_cplx.get())
1393       l.append(string.atof(self.entry1.get()))
1394       l.append(string.atof(self.entry2.get()))
1395       return `tuple(l)`
1396
1397   def erase_valeur(self):
1398       """
1399       Efface les entries de saisie
1400       """
1401       self.typ_cplx = 'RI'
1402       self.entry1.delete(0,END)
1403       self.entry2.delete(0,END)
1404       
1405 class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
1406   panel = newSIMPPanel
1407
1408   def init(self) :
1409       self.expandable = 0
1410       self.affect_panel()
1411
1412   def affect_panel(self):
1413       """
1414       Cette méthode attribue le panel à l'objet pointé par self en fonction de la
1415       nature de la valeur demandée pour cet objet
1416       """
1417       #print "affect_panel : ",self.nom,self.is_list(),self.has_into(), self.get_into(None)
1418       if self.wait_shell():
1419           # l'objet attend un shell
1420           self.panel = SHELLPanel
1421       elif self.has_into():
1422           # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
1423           if self.is_list() :
1424              self.panel = PLUSIEURS_INTO_Panel
1425           else:
1426              self.panel = UNIQUE_INTO_Panel
1427       else:
1428           # l'objet prend une ou des valeurs à priori quelconques
1429           if self.is_list() :
1430               # on attend une liste de valeurs mais de quel type ?
1431               if self.wait_assd():
1432                   # on attend une liste de SD
1433                   self.panel = PLUSIEURS_ASSD_Panel
1434               else:
1435                   # on attend une liste de valeurs de types debase (entiers, réels,...)
1436                   self.panel = PLUSIEURS_BASE_Panel
1437           else:
1438               # on n'attend qu'une seule valeur mais de quel type ?
1439               if self.wait_co():
1440                   # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
1441                   self.panel = UNIQUE_SDCO_Panel
1442               elif self.wait_assd():
1443                   # on attend une SD
1444                   self.panel = UNIQUE_ASSD_Panel
1445               else:
1446                   # on attend une valeur d'un type de base (entier,réel,...)
1447                   if self.wait_complex():
1448                       # on attend un complexe
1449                       self.panel = UNIQUE_COMP_Panel
1450                   else:
1451                       # on attend un entier, un réel ou une string
1452                       self.panel = UNIQUE_BASE_Panel
1453       print "affect_panel : ",self.panel
1454
1455   def is_list(self):
1456       """
1457           Cette méthode indique si le mot cle simple attend une liste (valeur de retour 1)
1458           ou s'il n'en attend pas (valeur de retour 0)
1459
1460           Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
1461           Dans le cas sans validateur, l'information est donnée par l'attribut max
1462           de la definition du mot cle.
1463           Dans le cas avec validateur, il faut combiner l'information précédente avec
1464           celle issue de l'appel de la méthode is_list sur le validateur.On utilisera
1465           l'operateur ET pour effectuer cette combinaison (AndVal).
1466       """
1467       is_a_list=0
1468       min,max = self.GetMinMax()
1469       assert (min <= max)
1470       if max > 1 :
1471                 is_a_list=1
1472       # Dans le cas avec validateurs, pour que le mot cle soit considéré
1473       # comme acceptant une liste, il faut que max soit supérieur a 1
1474       # ET que la méthode is_list du validateur retourne 1. Dans les autres cas
1475       # on retournera 0 (n'attend pas de liste)
1476       if self.definition.validators :
1477          is_a_list= self.definition.validators.is_list() * is_a_list
1478       return is_a_list 
1479
1480   def get_into(self,liste_courante=None):
1481       """
1482           Cette méthode retourne la liste de choix proposée par le mot cle. Si le mot cle ne propose
1483           pas de liste de choix, la méthode retourne None.
1484           L'argument d'entrée liste_courante, s'il est différent de None, donne la liste des choix déjà
1485           effectués par l'utilisateur. Dans ce cas, la méthode get_into doit calculer la liste des choix
1486           en en tenant compte.
1487           Cette méthode part du principe que la relation entre into du mot clé et les validateurs est
1488           une relation de type ET (AndVal).
1489       """
1490       if not self.object.definition.validators :
1491          return self.object.definition.into
1492       else:
1493          return self.object.definition.validators.get_into(liste_courante,self.definition.into)
1494
1495   def has_into(self):
1496       """
1497           Cette méthode indique si le mot cle simple propose un choix (valeur de retour 1)
1498           ou s'il n'en propose pas (valeur de retour 0)
1499
1500           Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
1501           Dans le cas sans validateur, l'information est donnée par l'attribut into
1502           de la definition du mot cle.
1503           Dans le cas avec validateurs, pour que le mot cle soit considéré
1504           comme proposant un choix, il faut que into soit présent OU
1505           que la méthode has_into du validateur retourne 1. Dans les autres cas
1506           on retournera 0 (ne propose pas de choix)
1507       """
1508       has_an_into=0
1509       if self.definition.into:
1510          has_an_into=1
1511       elif self.definition.validators :
1512          has_an_into= self.definition.validators.has_into()
1513       return has_an_into
1514
1515   def valide_item(self,item):
1516       """
1517         On fait un try except pour les erreurs de types (exple
1518         on rentre 1 pour une chaine de caracteres
1519       """
1520       valide=1
1521       if self.definition.validators :
1522          try :
1523             valide=self.definition.validators.verif_item(item)
1524          except :
1525             valide = 0
1526       return valide
1527      
1528   def valide_liste_partielle(self,item,listecourante):
1529       valeuravant=self.object.valeur
1530       valeur=listecourante
1531       valeur.append(item)
1532       valeur = tuple(valeur)
1533       retour=self.object.set_valeur(valeur)
1534       validite=0
1535       if self.object.isvalid():
1536          validite=1
1537       elif self.definition.validators :
1538          validite=self.definition.validators.valide_liste_partielle(valeur)
1539       if validite==0:
1540          min,max=self.GetMinMax()
1541          if len(valeur) < min :
1542             validite=1
1543       retour=self.object.set_valeur(valeuravant)
1544       return validite 
1545
1546   def valide_liste_complete (self,valeur):
1547       valeuravant=self.object.valeur
1548       retour=self.object.set_valeur(valeur)
1549       validite=0
1550       if self.object.isvalid():
1551          validite=1
1552       retour=self.object.set_valeur(valeuravant)
1553       return validite
1554      
1555   def info_erreur_item(self) :
1556       commentaire=""
1557       if self.definition.validators :
1558          commentaire=self.definition.validators.info_erreur_item()
1559       return commentaire
1560       
1561   def aide(self) :
1562       commentaire=""
1563       if self.definition.validators :
1564          commentaire=self.definition.validators.aide()
1565       return commentaire
1566
1567   def info_erreur_liste(self) :
1568       commentaire=""
1569       if self.definition.validators :
1570          commentaire=self.definition.validators.info_erreur_liste()
1571       return commentaire
1572
1573   def SetText(self, text):
1574     try:
1575       value = eval(text)
1576       self.object.setval(value)
1577     except:
1578       pass
1579
1580   def GetIconName(self):
1581     if self.isvalid():
1582       return "ast-green-ball"
1583     elif self.object.isoblig():
1584       return "ast-red-ball"
1585     else:
1586       return "ast-yel-ball"
1587
1588   def GetText(self):
1589     """
1590     Classe SIMPTreeItem
1591     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
1592     pointé par self 
1593     """
1594     text= self.object.GetText()
1595     return text
1596
1597   def wait_co(self):
1598       """
1599       Méthode booléenne qui retourne 1 si l'objet pointé par self
1600       attend un objet de type ASSD qui n'existe pas encore (type CO()),
1601       0 sinon
1602       """
1603       return self.object.wait_co()
1604
1605   def wait_geom(self):
1606       """
1607       Méthode booléenne qui retourne 1 si l'objet pointé par self
1608       attend un objet GEOM, 0 sinon
1609       """
1610       return self.object.wait_geom()
1611     
1612   def wait_complex(self):
1613       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1614       attend un complexe, 0 sinon """
1615       if 'C' in self.object.definition.type:
1616           return 1
1617       else:
1618           return 0
1619
1620   def wait_reel(self):
1621       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1622       attend un réel, 0 sinon """
1623       if 'R' in self.object.definition.type:
1624           return 1
1625       else:
1626           return 0
1627         
1628   def wait_shell(self):
1629       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1630       attend un shell, 0 sinon """
1631       if 'shell' in self.object.definition.type:
1632           return 1
1633       else:
1634           return 0
1635
1636   def wait_into(self):
1637       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1638       prend ses valeurs dans un ensemble discret (into), 0 sinon """
1639       if self.object.definition.into != None :
1640           return 1
1641       else:
1642           return 0
1643
1644   def wait_assd(self):
1645       """Méthode booléenne qui retourne 1 si l'objet pointé par self
1646       attend un objet de type ASSD ou dérivé, 0 sinon """
1647       return self.object.wait_assd()
1648     
1649   def getval(self):
1650       return self.object.getval()
1651     
1652   def GetMinMax(self):
1653       """ Retourne les valeurs min et max de la définition de object """
1654       return self.object.get_min_max()
1655
1656   def GetMultiplicite(self):
1657       """ A préciser.
1658           Retourne la multiplicité des valeurs affectées à l'objet
1659           représenté par l'item. Pour le moment retourne invariablement 1.
1660       """
1661       return 1
1662
1663   def GetType(self):
1664       """ 
1665           Retourne le type de valeur attendu par l'objet représenté par l'item.
1666       """
1667       return self.object.get_type()
1668
1669   def GetIntervalle(self):
1670       """ 
1671            Retourne le domaine de valeur attendu par l'objet représenté 
1672            par l'item.
1673       """
1674       return self.object.getintervalle()
1675
1676   def IsInIntervalle(self,valeur):
1677       """ 
1678           Retourne 1 si la valeur est dans l'intervalle permis par
1679           l'objet représenté par l'item.
1680       """
1681       return self.object.isinintervalle(valeur)
1682
1683   def set_valeur_co(self,nom_co):
1684       """
1685       Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
1686       """
1687       return self.object.set_valeur_co(nom_co)
1688       
1689   def get_sd_avant_du_bon_type(self):
1690       """
1691       Retourne la liste des noms des SD présentes avant l'étape qui contient
1692       le MCS pointé par self et du type requis par ce MCS
1693       """
1694       a=self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type)
1695       return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
1696                                                                self.object.definition.type)
1697     
1698   def GetListeValeurs(self) :
1699       """ Retourne la liste des valeurs de object """
1700       return self.object.get_liste_valeurs()
1701     
1702   def verif(self):
1703       pass
1704
1705   def isvalid(self):
1706     valide=self.object.isvalid()
1707     return self.object.isvalid()
1708
1709   def eval_valeur(self,valeur):
1710       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
1711       de l'objet pointé par self :
1712         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
1713         - retourne 'valeur' (chaîne de caractères) sinon
1714         - retourne None en cas d invalidite
1715         - retourne invalide si 1 des objets du tuple l est
1716       """
1717       validite=1
1718       if type(valeur) in (types.ListType,types.TupleType) :
1719          valeurretour=[]
1720          for item in valeur :
1721              newvaleur,validiteitem=self.eval_valeur_item(item)
1722              valeurretour.append(newvaleur)
1723              if validiteitem == 0:
1724                 validite=0
1725       else :
1726          valeurretour,validite= self.eval_valeur_item(valeur)
1727       if validite == 0 :
1728          valeurretour = None
1729       return valeurretour,validite
1730
1731   def eval_valeur_item(self,valeur):
1732       if valeur==None or valeur == "" :
1733          return None,0
1734       validite=1
1735       if self.wait_reel():
1736              valeurinter = self.traite_reel(valeur)
1737              valeurretour,validite= self.object.eval_valeur(valeurinter)
1738       elif self.wait_geom():
1739              valeurretour,validite = valeur,1
1740       else :
1741              valeurretour,validite= self.object.eval_valeur(valeur)
1742       if validite == 0:
1743          if type(valeur) == types.StringType and self.object.wait_TXM():
1744             essai_valeur="'" + valeur + "'"
1745             valeurretour,validite= self.object.eval_valeur(essai_valeur)
1746       if hasattr(valeurretour,'__class__'):
1747          if valeurretour.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
1748             validite=1
1749       if self.wait_co():
1750          try:
1751             valeurretour=Accas.CO(valeur)
1752          except:
1753             valeurretour=None
1754             validite=0
1755
1756       # on est dans le cas où on a évalué et où on n'aurait pas du
1757       if self.object.wait_TXM() :
1758           if type(valeurretour) != 'str':
1759                 if valeur[0]=="'" and valeur[-1]=="'" :
1760                    valeurretour=str(valeur)
1761                    validite=1
1762
1763       return valeurretour,validite
1764       
1765
1766   def is_CO(self,valeur=None):
1767       """
1768          Indique si valeur est un concept produit de la macro
1769          Cette méthode n'a de sens que pour un MCSIMP d'une MACRO
1770          Si valeur vaut None on teste la valeur du mot cle
1771       """
1772       # Pour savoir si un concept est un nouveau concept de macro
1773       # on regarde s'il est présent dans l'attribut sdprods de l'étape
1774       # ou si son nom de classe est CO.
1775       # Il faut faire les 2 tests car une macro non valide peut etre
1776       # dans un etat pas tres catholique avec des CO pas encore types
1777       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
1778       if not valeur:valeur=self.object.valeur
1779       if valeur in self.object.etape.sdprods:return 1
1780       if type(valeur) is not types.InstanceType:return 0
1781       if valeur.__class__.__name__ == 'CO':return 1
1782       return 0
1783
1784   def delete_valeur_co(self,valeur=None):
1785       """
1786            Supprime la valeur du mot cle (de type CO)
1787            il faut propager la destruction aux autres etapes
1788       """
1789       if not valeur : valeur=self.object.valeur
1790       # XXX faut il vraiment appeler del_sdprod ???
1791       #self.object.etape.parent.del_sdprod(valeur)
1792       self.object.etape.parent.delete_concept(valeur)
1793
1794   def get_liste_possible(self,listeActuelle=[]):
1795       if hasattr(self.definition.validators,'into'):
1796          self.get_definition().into=self.definition.validators.into 
1797       valeurspossibles = self.get_definition().into
1798       listevalideitem=[]
1799       for item in valeurspossibles:
1800           encorevalide=self.valide_item(item)
1801           if encorevalide :
1802              listevalideitem.append(item)
1803       # on ne verifie pas la liste des choix si max = 1 
1804       # (sinon cela enleve tous les choix possibles)
1805       min,max=self.GetMinMax()
1806       if max != 1 : 
1807          listevalideliste=[]
1808          for item in listevalideitem:
1809              listetravail=[]
1810              for item2 in listeActuelle : listetravail.append(item2)
1811              encorevalide=self.valide_liste_partielle(item,listetravail)
1812              if encorevalide :
1813                 listevalideliste.append(item)
1814       else :
1815          listevalideliste=listevalideitem
1816       return listevalideliste
1817
1818   def traite_reel(self,valeur):
1819       """
1820       Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
1821       ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
1822       ou un EVAL ...
1823       """
1824       valeur = string.strip(valeur)
1825       liste_reels = self.get_sd_avant_du_bon_type()
1826       if valeur in liste_reels:
1827           return valeur
1828       if len(valeur) >= 3 :
1829           if valeur[0:4] == 'EVAL' :
1830               # on a trouvé un EVAL --> on retourne directement la valeur
1831               return valeur
1832       if string.find(valeur,'.') == -1 :
1833           # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
1834           return valeur+'.'
1835       else:
1836           return valeur
1837         
1838
1839 import Accas
1840 treeitem = SIMPTreeItem
1841 objet = Accas.MCSIMP
1842