Salome HOME
b8aaba32ad871531964cc9838fbfa297d15ca137
[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       if not test :
952           mess = "impossible d'évaluer : %s " %`valeur`
953           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
954       elif self.node.item.isvalid() :
955           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
956           if self.node.item.get_position()=='global':
957               self.node.etape.verif_all()
958           elif self.node.item.get_position()=='global_jdc':
959               self.node.racine.verif_all()
960           else :
961               self.node.parent.verif()
962           self.node.update()
963       else :
964           cr = self.node.item.get_cr()
965           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
966           self.reset_old_valeur(anc_val,mess=mess)
967
968   def makeValeurPage(self,page):
969       """
970           Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une 
971           SD de type dérivé d'ASSD
972       """
973       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
974       # et de la liste des SD du bon type (constituant la liste des choix)
975       bulle_aide=self.get_bulle_aide()
976       aide=self.get_aide()
977       aide= justify_text(texte=aide)
978       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
979       # Remplissage du panneau
980       self.valeur_choisie = StringVar()
981       self.valeur_choisie.set('')
982       min,max =  self.node.item.GetMinMax()
983       if (min == 1 and min == max and len(liste_noms_sd)==1):
984           if self.valeur_choisie.get() != liste_noms_sd[0]:
985              self.valeur_choisie.set(liste_noms_sd[0])
986              self.valid_valeur_automatique()
987          
988       self.frame_valeur = Frame(page)
989       self.frame_valeur.pack(fill='both',expand=1)
990       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
991       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
992       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
993                                          items=liste_noms_sd,
994                                          labelpos='n',
995                                          label_text="Structures de données du type\n requis par l'objet courant :",
996                                          listbox_height = 6,
997                                          selectioncommand=self.select_valeur_from_list,
998                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
999       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
1000       Label(self.frame_valeur,text='Structure de donnée choisie :').place(relx=0.05,rely=0.6)
1001       #self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
1002       Label(self.frame_valeur,textvariable=self.valeur_choisie).place(relx=0.5,rely=0.6)
1003       # affichage de la valeur courante
1004       self.display_valeur()
1005
1006   def get_bulle_aide(self):
1007       """
1008       Retourne l'aide associée au panneau
1009       """
1010       return "Double-cliquez sur la structure de donnée désirée pour valoriser le mot-clé simple courant"
1011
1012   def get_aide(self):
1013       """
1014       Retourne la phrase d'aide indiquant de quel type doit être la valeur à donner par l'utilisateur
1015       """
1016       mc = self.node.item.get_definition()
1017       type = mc.type[0].__name__  
1018       if len(mc.type)>1 :
1019           for typ in mc.type[1:] :
1020               type = type + ' ou '+typ.__name__
1021       commentaire="Un objet de type "+type+" est attendu"
1022       aideval=self.node.item.aide()
1023       commentaire=commentaire +"\n"+ aideval
1024       return commentaire
1025
1026     
1027   def select_valeur_from_list(self):
1028       """
1029       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
1030       """
1031       if len(self.listbox.get()) == 0 : return
1032       choix = self.listbox.getcurselection()[0]
1033       self.valeur_choisie.set(choix)
1034
1035   def choose_valeur_from_list(self,command):
1036       """
1037       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
1038       Exécute command
1039       """
1040       if len(self.listbox.get()) == 0 : return
1041       choix = self.listbox.getcurselection()[0]
1042       self.valeur_choisie.set(choix)
1043       apply(command,(),{})
1044
1045   def get_valeur(self):
1046       """
1047       Retourne la valeur donnée par l'utilisateur au MCS
1048       """
1049       return self.valeur_choisie.get()
1050     
1051   def display_valeur(self):
1052       """
1053       Affiche la valeur de l'objet pointé par self
1054       """
1055       valeur = self.node.item.get_valeur()
1056       if valeur == None or valeur == '' : return # pas de valeur à afficher ...
1057       self.valeur_choisie.set(valeur.nom)
1058
1059   def erase_valeur(self):
1060       pass
1061
1062 class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel):
1063   """
1064   Classe servant à définir le panneau correspondant à un mot-clé simple
1065   qui attend une valeur unique de type dérivé d'ASSD ou non encore
1066   existante (type CO(...) utilisé dans les macros uniquement)
1067   """
1068   def makeValeurPage(self,page):
1069       """
1070       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une SD de type dérivé
1071       d'ASSD
1072       """
1073       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
1074       # et de la liste des SD du bon type (constituant la liste des choix)
1075       bulle_aide=self.get_bulle_aide()
1076       aide=self.get_aide()
1077       aide= justify_text(texte=aide)
1078       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
1079       # Remplissage du panneau
1080       self.frame_valeur = Frame(page)
1081       self.frame_valeur.pack(fill='both',expand=1)
1082       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1083       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1084       # affichage de la liste des SD existantes et du bon type
1085       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
1086                                          items=liste_noms_sd,
1087                                          labelpos='n',
1088                                          label_text="Structures de données du type\n requis par l'objet courant :",
1089                                          listbox_height = 6,
1090                                          selectioncommand=self.select_valeur_from_list,
1091                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
1092       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
1093       # affichage du bouton 'Nouveau concept'
1094       self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ",
1095                                  items = ('NON','OUI'),menubutton_width=10)
1096       self.b_co.configure(command = lambda e,s=self : s.ask_new_concept())
1097       self.b_co.place(relx=0.05,rely=0.6,anchor='w')
1098       self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :')
1099       self.entry_co = Entry(self.frame_valeur)
1100       self.entry_co.bind('<Return>',self.valid_nom_concept_co)
1101       # affichage du label de la structure de donnée choisie
1102       self.l_resu = Label(self.frame_valeur,text='Structure de donnée choisie :')
1103       self.valeur_choisie = StringVar()
1104       self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
1105       self.frame_valeur.update()
1106       self.aide = Label(self.frame_valeur,
1107                         text = aide,
1108                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1109                         justify='center')
1110       self.aide.place(relx=0.5,rely=0.85,anchor='n')
1111       # affichage de la valeur courante
1112       self.display_valeur()
1113       
1114   def get_bulle_aide(self):
1115       """
1116       Retourne la bulle d'aide du panneau
1117       """
1118       return """Double-cliquez sur la structure de donnée désirée
1119       pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour
1120       entrer le nom d'un concept non encore existant"""
1121
1122   def valid_valeur(self):
1123       """
1124       Teste si la valeur fournie par l'utilisateur est une valeur permise :
1125       - si oui, l'enregistre
1126       - si non, restaure l'ancienne valeur
1127       """
1128       if self.parent.modified == 'n' : self.parent.init_modif()
1129       valeur = self.get_valeur()
1130       self.erase_valeur()
1131       anc_val = self.node.item.get_valeur()
1132       test_CO=self.node.item.is_CO(anc_val)
1133       test = self.node.item.set_valeur(valeur)
1134       if not test :
1135           mess = "impossible d'évaluer : %s " %`valeur`
1136           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
1137           return
1138       elif self.node.item.isvalid() :
1139           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
1140           if test_CO:
1141              # il faut egalement propager la destruction de l'ancien concept
1142              self.node.item.delete_valeur_co(valeur=anc_val)
1143              # et on force le recalcul des concepts de sortie de l'etape
1144              self.node.item.object.etape.get_type_produit(force=1)
1145              # et le recalcul du contexte
1146              self.node.item.object.etape.parent.reset_context()
1147           self.node.parent.select()
1148       else :
1149           cr = self.node.item.get_cr()
1150           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
1151           self.reset_old_valeur(anc_val,mess=mess)
1152           return
1153       if self.node.item.get_position()=='global':
1154           self.node.etape.verif_all()
1155       elif self.node.item.get_position()=='global_jdc':
1156           self.node.racine.verif_all()
1157       else :
1158           self.node.parent.verif()
1159       self.node.update()
1160
1161   def valid_nom_concept_co(self,event=None):
1162       """
1163       Lit le nom donné par l'utilisateur au concept de type CO qui doit être
1164       la valeur du MCS courant et stocke cette valeur
1165       """
1166       if self.parent.modified == 'n' : self.parent.init_modif()
1167       anc_val = self.node.item.get_valeur()
1168       nom_concept = self.entry_co.get()
1169       test,mess=self.node.item.set_valeur_co(nom_concept)
1170       if not test:
1171           # On n'a pas pu créer le concept
1172           self.parent.appli.affiche_infos(mess)
1173           return
1174       elif self.node.item.isvalid() :
1175           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
1176           self.node.parent.select()
1177       else :
1178           cr = self.node.item.get_cr()
1179           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
1180           self.reset_old_valeur(anc_val,mess=mess)
1181           return
1182       if self.node.item.get_position()=='global':
1183           self.node.etape.verif_all()
1184       elif self.node.item.get_position()=='global_jdc':
1185           self.node.racine.verif_all()
1186       else :
1187           self.node.parent.verif()
1188       if self.node.item.isvalid():
1189           self.node.parent.select()
1190       self.node.update()
1191
1192   def ask_new_concept(self):
1193       """
1194       Crée une entry dans le panneau d'un MCS qui attend un concept OU un CO() afin de
1195       permettre à l'utilisateur de donner le nom du nouveau concept
1196       """
1197       new_concept = self.b_co.getcurselection()
1198       if new_concept == 'OUI':
1199           self.label_co.place(relx=0.05,rely=0.7)
1200           self.entry_co.place(relx=0.45,rely=0.7,relwidth=0.25)
1201           self.l_resu.place_forget()
1202           self.label_valeur.place_forget()
1203           self.entry_co.focus()
1204       elif new_concept == 'NON':
1205           # On est passe de OUI à NON, on supprime la valeur
1206 # PN correction de bug (on passe de non a non et cela supprime la valeur)
1207 # ajout du if de le ligne suivane
1208           if self.node.item.is_CO():
1209                 self.node.item.delete_valeur_co()
1210                 self.record_valeur(name=None,mess="Suppression CO enregistrée")
1211                 self.label_co.place_forget()
1212                 self.entry_co.place_forget()
1213                 self.l_resu.place(relx=0.05,rely=0.7)
1214                 self.label_valeur.place(relx=0.45,rely=0.7)
1215           
1216   def display_valeur(self):
1217       """
1218       Affiche la valeur de l'objet pointé par self
1219       """
1220       valeur = self.node.item.get_valeur()
1221       if valeur == None or valeur == '': 
1222          self.valeur_choisie.set('')
1223          return # pas de valeur à afficher ...
1224       # il faut configurer le bouton si la valeur est un objet CO
1225       # sinon afficher le nom du concept dans self.valeur_choisie
1226       if self.node.item.is_CO():
1227           self.b_co.invoke('OUI')
1228           self.entry_co.insert(0,valeur.nom)
1229       else:
1230           self.valeur_choisie.set(valeur.nom)
1231
1232   def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
1233       """
1234       Enregistre  val comme valeur de self.node.item.object SANS faire de test de validité
1235       """
1236       if self.parent.modified == 'n' : self.parent.init_modif()
1237       if name != None:
1238           valeur =name
1239       else :
1240           self.entry_co.delete(0,END)
1241           valeur= self.entry_co.get()
1242       self.node.item.set_valeur_co(valeur)
1243       self.parent.appli.affiche_infos(mess)
1244       # On met a jour le display dans le panneau
1245       self.display_valeur()
1246       if self.node.item.get_position()=='global':
1247           self.node.etape.verif_all()
1248       elif self.node.item.get_position()=='global_jdc':
1249           self.node.racine.verif_all()
1250       else :
1251           self.node.parent.verif()
1252       if self.node.item.isvalid():
1253           self.node.parent.select()
1254       self.node.update()
1255
1256
1257 class UNIQUE_BASE_Panel(UNIQUE_Panel):
1258   """
1259   Classe servant à définir le panneau associé aux mots-clés simples qui attendent
1260   une valeur d'un type de base (entier, réel ou string).
1261   """
1262   def makeValeurPage(self,page):
1263       """
1264       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1265       de base cad entier, réel, string ou complexe
1266       """
1267       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
1268       # et de la liste des SD du bon type (constituant la liste des choix)
1269       bulle_aide=self.get_bulle_aide()
1270       aide=self.get_aide()
1271       aide= justify_text(texte=aide)
1272       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
1273       # Remplissage du panneau
1274       self.frame_valeur = Frame(page)
1275       self.frame_valeur.pack(fill='both',expand=1)
1276       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1277       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1278       self.label = Label(self.frame_valeur,text='Valeur :')
1279       self.label.place(relx=0.1,rely=0.5)
1280       self.entry = Entry(self.frame_valeur,relief='sunken')
1281       self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
1282       self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
1283       self.entry.focus()
1284       # aide associée au panneau
1285       self.frame_valeur.update()
1286       self.aide = Label(self.frame_valeur, 
1287                         text = aide,
1288                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1289                         justify='center')
1290       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1291       # affichage de la valeur du MCS
1292       self.display_valeur()
1293
1294   def get_aide(self):
1295       """
1296       Retourne la phrase d'aide indiquant de quel type doit être la valeur
1297       du mot-clé simple fournie par l'utilisateur
1298       """
1299       mc = self.node.item.get_definition()
1300       d_aides = { 'TXM' : "Une chaîne de caractères est attendue",
1301                   'R'   : "Un réel est attendu",
1302                   'I'   : "Un entier est attendu"}
1303       type = mc.type[0]
1304       commentaire=d_aides.get(type,"Type de base inconnu")
1305       aideval=self.node.item.aide()
1306       commentaire=commentaire +"\n"+ aideval
1307       return commentaire
1308
1309   def get_bulle_aide(self):
1310       """
1311       Retourne la bulle d'aide associée au panneau et affichée par clic droit
1312       """
1313       return """Saisissez la valeur que vous voulez affecter au mot-clé simple
1314       dans la zone de saisie et pressez <Return>"""
1315       
1316   def display_valeur(self):
1317       """
1318       Affiche la valeur de l'objet pointé par self
1319       """
1320       valeur = self.node.item.get_valeur()
1321       if valeur == None or valeur == '' : return # pas de valeur à afficher ...
1322       self.entry.delete(0,END)
1323       self.entry.insert(0,valeur)
1324       self.entry.focus()
1325       
1326 class UNIQUE_COMP_Panel(UNIQUE_Panel):
1327   """
1328   Classe servant à définir le panneau associé aux mots-clés simples
1329   qui attendent une valeur de type complexe
1330   """
1331   def makeValeurPage(self,page):
1332       """
1333       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1334       de base cad entier, réel, string ou complexe
1335       """
1336       # Récupération de l'aide associée au panneau et de l'aide destinée à l'utilisateur
1337       bulle_aide=self.get_bulle_aide()
1338       aide=self.get_aide()
1339       aide= justify_text(texte=aide)
1340       # Remplissage du panneau
1341       self.frame_valeur = Frame(page)
1342       self.frame_valeur.pack(fill='both',expand=1)
1343       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1344       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1345       self.label = Label(self.frame_valeur,text='Valeur :')
1346       self.label.place(relx=0.1,rely=0.5)
1347       self.typ_cplx=StringVar()
1348       self.typ_cplx.set('RI')
1349       rb1 = Radiobutton(self.frame_valeur, text='RI',variable=self.typ_cplx,value='RI')
1350       rb2 = Radiobutton(self.frame_valeur, text='MP',variable=self.typ_cplx,value='MP')
1351       self.entry1 = Pmw.EntryField(self.frame_valeur,validate='real')
1352       self.entry2 = Pmw.EntryField(self.frame_valeur,validate='real')
1353       rb1.place(relx=0.05,rely = 0.4)
1354       rb2.place(relx=0.05,rely = 0.6)
1355       self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus())
1356       self.entry2.component('entry').bind("<Return>",lambda e,c=self.valid_valeur:c())
1357       self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
1358       self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
1359       self.entry1.focus()
1360       self.frame_valeur.update()
1361       self.aide = Label(self.frame_valeur,
1362                         text = aide,
1363                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1364                         justify='center')
1365       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1366       # affichage de la valeur du MCS
1367       self.display_valeur()
1368
1369   def display_valeur(self):
1370       """
1371       Affiche la valeur de l'objet pointé par self
1372       """
1373       valeur = self.node.item.get_valeur()
1374       if valeur == None or valeur == '' : return # pas de valeur à afficher ...
1375       typ_cplx,x1,x2=valeur
1376       self.entry1.delete(0,END)
1377       self.entry2.delete(0,END)
1378       self.typ_cplx.set(typ_cplx)
1379       self.entry1.setentry(x1)
1380       self.entry2.setentry(x2)
1381
1382   def get_bulle_aide(self):
1383       """
1384       Retourne la bulle d'aide du panneau
1385       """
1386       return """-Choisissez votre format de saisie du complexe :
1387       \t 'RI' = parties réelle et imaginaire
1388       \t 'MP' = module/phase (en degrés)
1389       - Saisissez ensuite dans les deux zones de saisie les deux nombres attendus"""
1390
1391   def get_aide(self):
1392       """
1393       Retourne la phrase d'aide décrivant le type de la valeur que peut prendre
1394       le mot-clé simple courant
1395       """
1396       commentaire='Un complexe est attendu'
1397       aideval=self.node.item.aide()
1398       commentaire=commentaire +"\n"+ aideval
1399       return commentaire
1400
1401   def get_valeur(self):
1402       """
1403       Retourne le complexe saisi par l'utilisateur
1404       """
1405       l=[]
1406       l.append(self.typ_cplx.get())
1407       l.append(string.atof(self.entry1.get()))
1408       l.append(string.atof(self.entry2.get()))
1409       return `tuple(l)`
1410
1411   def erase_valeur(self):
1412       """
1413       Efface les entries de saisie
1414       """
1415       self.typ_cplx = 'RI'
1416       self.entry1.delete(0,END)
1417       self.entry2.delete(0,END)
1418       
1419 class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
1420   panel = newSIMPPanel
1421
1422   def init(self) :
1423       self.expandable = 0
1424       self.affect_panel()
1425
1426   def affect_panel(self):
1427       """
1428       Cette méthode attribue le panel à l'objet pointé par self en fonction de la
1429       nature de la valeur demandée pour cet objet
1430       """
1431       #print "affect_panel : ",self.nom,self.is_list(),self.has_into(), self.get_into(None)
1432       if self.wait_shell():
1433           # l'objet attend un shell
1434           self.panel = SHELLPanel
1435       elif self.has_into():
1436           # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
1437           if self.is_list() :
1438              self.panel = PLUSIEURS_INTO_Panel
1439           else:
1440              self.panel = UNIQUE_INTO_Panel
1441       else:
1442           # l'objet prend une ou des valeurs à priori quelconques
1443           if self.is_list() :
1444               # on attend une liste de valeurs mais de quel type ?
1445               if self.wait_assd():
1446                   # on attend une liste de SD
1447                   self.panel = PLUSIEURS_ASSD_Panel
1448               else:
1449                   # on attend une liste de valeurs de types debase (entiers, réels,...)
1450                   self.panel = PLUSIEURS_BASE_Panel
1451           else:
1452               # on n'attend qu'une seule valeur mais de quel type ?
1453               if self.wait_co():
1454                   # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
1455                   self.panel = UNIQUE_SDCO_Panel
1456               elif self.wait_assd():
1457                   # on attend une SD
1458                   self.panel = UNIQUE_ASSD_Panel
1459               else:
1460                   # on attend une valeur d'un type de base (entier,réel,...)
1461                   if self.wait_complex():
1462                       # on attend un complexe
1463                       self.panel = UNIQUE_COMP_Panel
1464                   else:
1465                       # on attend un entier, un réel ou une string
1466                       self.panel = UNIQUE_BASE_Panel
1467       #print "affect_panel : ",self.panel
1468
1469   def is_list(self):
1470       """
1471           Cette méthode indique si le mot cle simple attend une liste (valeur de retour 1)
1472           ou s'il n'en attend pas (valeur de retour 0)
1473
1474           Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
1475           Dans le cas sans validateur, l'information est donnée par l'attribut max
1476           de la definition du mot cle.
1477           Dans le cas avec validateur, il faut combiner l'information précédente avec
1478           celle issue de l'appel de la méthode is_list sur le validateur.On utilisera
1479           l'operateur ET pour effectuer cette combinaison (AndVal).
1480       """
1481       is_a_list=0
1482       min,max = self.GetMinMax()
1483       assert (min <= max)
1484       if max > 1 :
1485                 is_a_list=1
1486       # Dans le cas avec validateurs, pour que le mot cle soit considéré
1487       # comme acceptant une liste, il faut que max soit supérieur a 1
1488       # ET que la méthode is_list du validateur retourne 1. Dans les autres cas
1489       # on retournera 0 (n'attend pas de liste)
1490       if self.definition.validators :
1491          is_a_list= self.definition.validators.is_list() * is_a_list
1492       return is_a_list 
1493
1494   def get_into(self,liste_courante=None):
1495       """
1496           Cette méthode retourne la liste de choix proposée par le mot cle. Si le mot cle ne propose
1497           pas de liste de choix, la méthode retourne None.
1498           L'argument d'entrée liste_courante, s'il est différent de None, donne la liste des choix déjà
1499           effectués par l'utilisateur. Dans ce cas, la méthode get_into doit calculer la liste des choix
1500           en en tenant compte.
1501           Cette méthode part du principe que la relation entre into du mot clé et les validateurs est
1502           une relation de type ET (AndVal).
1503       """
1504       if not self.object.definition.validators :
1505          return self.object.definition.into
1506       else:
1507          return self.object.definition.validators.get_into(liste_courante,self.definition.into)
1508
1509   def has_into(self):
1510       """
1511           Cette méthode indique si le mot cle simple propose un choix (valeur de retour 1)
1512           ou s'il n'en propose pas (valeur de retour 0)
1513
1514           Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
1515           Dans le cas sans validateur, l'information est donnée par l'attribut into
1516           de la definition du mot cle.
1517           Dans le cas avec validateurs, pour que le mot cle soit considéré
1518           comme proposant un choix, il faut que into soit présent OU
1519           que la méthode has_into du validateur retourne 1. Dans les autres cas
1520           on retournera 0 (ne propose pas de choix)
1521       """
1522       has_an_into=0
1523       if self.definition.into:
1524          has_an_into=1
1525       elif self.definition.validators :
1526          has_an_into= self.definition.validators.has_into()
1527       return has_an_into
1528
1529   def valide_item(self,item):
1530       """
1531         On fait un try except pour les erreurs de types (exple
1532         on rentre 1 pour une chaine de caracteres
1533       """
1534       valide=1
1535       if self.definition.validators :
1536          try :
1537             valide=self.definition.validators.verif_item(item)
1538          except :
1539             valide = 0
1540       return valide
1541      
1542   def valide_liste_partielle(self,item,listecourante):
1543       valeuravant=self.object.valeur
1544       valeur=listecourante
1545       valeur.append(item)
1546       valeur = tuple(valeur)
1547       retour=self.object.set_valeur(valeur)
1548       validite=0
1549       if self.object.isvalid():
1550          validite=1
1551       elif self.definition.validators :
1552          validite=self.definition.validators.valide_liste_partielle(valeur)
1553
1554       if validite==0:
1555          min,max=self.GetMinMax()
1556          if len(valeur) < min :
1557             validite=1
1558       retour=self.object.set_valeur(valeuravant)
1559       return validite 
1560
1561   def valide_liste_complete (self,valeur):
1562       valeuravant=self.object.valeur
1563       retour=self.object.set_valeur(valeur)
1564       validite=0
1565       if self.object.isvalid():
1566          validite=1
1567       retour=self.object.set_valeur(valeuravant)
1568       return validite
1569      
1570   def info_erreur_item(self) :
1571       commentaire=""
1572       if self.definition.validators :
1573          commentaire=self.definition.validators.info_erreur_item()
1574       return commentaire
1575       
1576   def aide(self) :
1577       commentaire=""
1578       if self.definition.validators :
1579          commentaire=self.definition.validators.aide()
1580       return commentaire
1581
1582   def info_erreur_liste(self) :
1583       commentaire=""
1584       if self.definition.validators :
1585          commentaire=self.definition.validators.info_erreur_liste()
1586       return commentaire
1587
1588   def SetText(self, text):
1589     try:
1590       value = eval(text)
1591       self.object.setval(value)
1592     except:
1593       pass
1594
1595   def GetIconName(self):
1596     if self.isvalid():
1597       return "ast-green-ball"
1598     elif self.object.isoblig():
1599       return "ast-red-ball"
1600     else:
1601       return "ast-yel-ball"
1602
1603   def GetText(self):
1604     """
1605     Classe SIMPTreeItem
1606     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
1607     pointé par self 
1608     """
1609     text= self.object.GetText()
1610     return text
1611
1612   def wait_co(self):
1613       """
1614       Méthode booléenne qui retourne 1 si l'objet pointé par self
1615       attend un objet de type ASSD qui n'existe pas encore (type CO()),
1616       0 sinon
1617       """
1618       return self.object.wait_co()
1619
1620   def wait_geom(self):
1621       """
1622       Méthode booléenne qui retourne 1 si l'objet pointé par self
1623       attend un objet GEOM, 0 sinon
1624       """
1625       return self.object.wait_geom()
1626     
1627   def wait_complex(self):
1628       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1629       attend un complexe, 0 sinon """
1630       if 'C' in self.object.definition.type:
1631           return 1
1632       else:
1633           return 0
1634
1635   def wait_reel(self):
1636       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1637       attend un réel, 0 sinon """
1638       if 'R' in self.object.definition.type:
1639           return 1
1640       else:
1641           return 0
1642         
1643   def wait_shell(self):
1644       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1645       attend un shell, 0 sinon """
1646       if 'shell' in self.object.definition.type:
1647           return 1
1648       else:
1649           return 0
1650
1651   def wait_into(self):
1652       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1653       prend ses valeurs dans un ensemble discret (into), 0 sinon """
1654       if self.object.definition.into != None :
1655           return 1
1656       else:
1657           return 0
1658
1659   def wait_assd(self):
1660       """Méthode booléenne qui retourne 1 si l'objet pointé par self
1661       attend un objet de type ASSD ou dérivé, 0 sinon """
1662       return self.object.wait_assd()
1663     
1664   def getval(self):
1665       return self.object.getval()
1666     
1667   def GetMinMax(self):
1668       """ Retourne les valeurs min et max de la définition de object """
1669       return self.object.get_min_max()
1670
1671   def GetMultiplicite(self):
1672       """ A préciser.
1673           Retourne la multiplicité des valeurs affectées à l'objet
1674           représenté par l'item. Pour le moment retourne invariablement 1.
1675       """
1676       return 1
1677
1678   def GetType(self):
1679       """ 
1680           Retourne le type de valeur attendu par l'objet représenté par l'item.
1681       """
1682       return self.object.get_type()
1683
1684   def GetIntervalle(self):
1685       """ 
1686            Retourne le domaine de valeur attendu par l'objet représenté 
1687            par l'item.
1688       """
1689       return self.object.getintervalle()
1690
1691   def IsInIntervalle(self,valeur):
1692       """ 
1693           Retourne 1 si la valeur est dans l'intervalle permis par
1694           l'objet représenté par l'item.
1695       """
1696       return self.object.isinintervalle(valeur)
1697
1698   def set_valeur_co(self,nom_co):
1699       """
1700       Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
1701       """
1702       return self.object.set_valeur_co(nom_co)
1703       
1704   def get_sd_avant_du_bon_type(self):
1705       """
1706       Retourne la liste des noms des SD présentes avant l'étape qui contient
1707       le MCS pointé par self et du type requis par ce MCS
1708       """
1709       a=self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type)
1710       return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
1711                                                                self.object.definition.type)
1712     
1713   def GetListeValeurs(self) :
1714       """ Retourne la liste des valeurs de object """
1715       return self.object.get_liste_valeurs()
1716     
1717   def verif(self):
1718       pass
1719
1720   def isvalid(self):
1721     valide=self.object.isvalid()
1722     return self.object.isvalid()
1723
1724   def eval_valeur(self,valeur):
1725       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
1726       de l'objet pointé par self :
1727         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
1728         - retourne 'valeur' (chaîne de caractères) sinon
1729         - retourne None en cas d invalidite
1730         - retourne invalide si 1 des objets du tuple l est
1731       """
1732       validite=1
1733       if type(valeur) in (types.ListType,types.TupleType) :
1734          valeurretour=[]
1735          for item in valeur :
1736              newvaleur,validiteitem=self.eval_valeur_item(item)
1737              valeurretour.append(newvaleur)
1738              if validiteitem == 0:
1739                 validite=0
1740       else :
1741          valeurretour,validite= self.eval_valeur_item(valeur)
1742       if validite == 0 :
1743          valeurretour = None
1744       return valeurretour,validite
1745
1746   def eval_valeur_item(self,valeur):
1747       if valeur==None or valeur == "" :
1748          return None,0
1749       validite=1
1750       if self.wait_reel():
1751              valeurinter = self.traite_reel(valeur)
1752              valeurretour,validite= self.object.eval_valeur(valeurinter)
1753       elif self.wait_geom():
1754              valeurretour,validite = valeur,1
1755       else :
1756              valeurretour,validite= self.object.eval_valeur(valeur)
1757       if validite == 0:
1758          if type(valeur) == types.StringType and self.object.wait_TXM():
1759             essai_valeur="'" + valeur + "'"
1760             valeurretour,validite= self.object.eval_valeur(essai_valeur)
1761       if hasattr(valeurretour,'__class__'):
1762          if valeurretour.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
1763             validite=1
1764       if self.wait_co():
1765          try:
1766             valeurretour=Accas.CO(valeur)
1767          except:
1768             valeurretour=None
1769             validite=0
1770
1771       # on est dans le cas où on a évalué et où on n'aurait pas du
1772       if self.object.wait_TXM() :
1773           if type(valeurretour) != types.StringType:
1774              valeurretour=str(valeur)
1775              validite=1
1776
1777       return valeurretour,validite
1778       
1779
1780   def is_CO(self,valeur=None):
1781       """
1782          Indique si valeur est un concept produit de la macro
1783          Cette méthode n'a de sens que pour un MCSIMP d'une MACRO
1784          Si valeur vaut None on teste la valeur du mot cle
1785       """
1786       # Pour savoir si un concept est un nouveau concept de macro
1787       # on regarde s'il est présent dans l'attribut sdprods de l'étape
1788       # ou si son nom de classe est CO.
1789       # Il faut faire les 2 tests car une macro non valide peut etre
1790       # dans un etat pas tres catholique avec des CO pas encore types
1791       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
1792       if not valeur:valeur=self.object.valeur
1793       if valeur in self.object.etape.sdprods:return 1
1794       if type(valeur) is not types.InstanceType:return 0
1795       if valeur.__class__.__name__ == 'CO':return 1
1796       return 0
1797
1798   def delete_valeur_co(self,valeur=None):
1799       """
1800            Supprime la valeur du mot cle (de type CO)
1801            il faut propager la destruction aux autres etapes
1802       """
1803       if not valeur : valeur=self.object.valeur
1804       # XXX faut il vraiment appeler del_sdprod ???
1805       #self.object.etape.parent.del_sdprod(valeur)
1806       self.object.etape.parent.delete_concept(valeur)
1807
1808   def get_liste_possible(self,listeActuelle=[]):
1809       if hasattr(self.definition.validators,'into'):
1810          self.get_definition().into=self.definition.validators.into 
1811       valeurspossibles = self.get_definition().into
1812       # CCAR : Ne serait-il pas preferable d'appeler get_into ?
1813       #valeurspossibles=self.get_into(listeActuelle)
1814
1815       listevalideitem=[]
1816       for item in valeurspossibles:
1817           encorevalide=self.valide_item(item)
1818           if encorevalide :
1819              listevalideitem.append(item)
1820       # on ne verifie pas la liste des choix si max = 1 
1821       # (sinon cela enleve tous les choix possibles)
1822       min,max=self.GetMinMax()
1823       if max != 1 : 
1824          listevalideliste=[]
1825          for item in listevalideitem:
1826              listetravail=[]
1827              for item2 in listeActuelle : listetravail.append(item2)
1828              encorevalide=self.valide_liste_partielle(item,listetravail)
1829              if encorevalide :
1830                 listevalideliste.append(item)
1831       else :
1832          listevalideliste=listevalideitem
1833       return listevalideliste
1834
1835   def traite_reel(self,valeur):
1836       """
1837       Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
1838       ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
1839       ou un EVAL ...
1840       """
1841       valeur = string.strip(valeur)
1842       liste_reels = self.get_sd_avant_du_bon_type()
1843       if valeur in liste_reels:
1844           return valeur
1845       if len(valeur) >= 3 :
1846           if valeur[0:4] == 'EVAL' :
1847               # on a trouvé un EVAL --> on retourne directement la valeur
1848               return valeur
1849       if string.find(valeur,'.') == -1 :
1850           # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
1851           return valeur+'.'
1852       else:
1853           return valeur
1854         
1855
1856 import Accas
1857 treeitem = SIMPTreeItem
1858 objet = Accas.MCSIMP
1859