]> SALOME platform Git repositories - tools/eficas.git/blob - Editeur/composimp.py
Salome HOME
F.R: composimp.py : dans méthode select_in_file, ajout d'un paramètre manquant dans le
[tools/eficas.git] / Editeur / composimp.py
1 #@ MODIF composimp Editeur  DATE 05/09/2001   AUTEUR DURAND C.DURAND 
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2001  EDF R&D                  WWW.CODE-ASTER.ORG
5 #              SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND
6 #              REDISTRIBUTION OF THIS FILE.
7 # ======================================================================
8 # Modules Python
9 import string,types,os
10 from Tkinter import *
11 import Pmw
12 from tkFileDialog import *
13 from tkMessageBox import showinfo
14 from copy import copy,deepcopy
15 import traceback
16
17 # Modules Eficas
18 import Objecttreeitem
19 import prefs
20 import panels
21 import images
22 from widgets import ListeChoix
23 from widgets import FenetreDeSelection
24
25 from Noyau.N_CR import justify_text
26 from utils import substract_list
27
28
29 class newSIMPPanel(panels.OngletPanel):
30   """
31   Classe virtuelle servant de classe mère à toutes les classes Panel
32   servant à afficher et récupérer la valeur d'un mot-clé simple.
33   Le panel est différent suivant le type de la valeur attendu
34   """
35   def init(self):
36       """
37       Méthode appelée par le constructeur de OngletPanel :
38       construit le notebook à 2 onglets utilisé par tous les panels de
39       tous les mots-clés simples
40       """
41       nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
42       nb.pack(fill = 'both', expand = 1)
43       self.nb=nb
44       nb.add('Valeur', tab_text='Saisir valeur')
45       #nb.add('Commentaire',tab_text='Insérer commentaire')
46       self.makeValeurPage(nb.page('Valeur'))
47       #self.makeCommentairePage(nb.page("Commentaire"))
48       nb.setnaturalsize()
49       
50 # ----------------------------------------------------------------------------------------
51 #   Méthodes utlisées pour l'affectation de la valeur donnée par l'utilisateur
52 #    au mot-clé courant
53 # ----------------------------------------------------------------------------------------
54
55   def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
56       """
57           Enregistre  val comme valeur de self.node.item.object SANS 
58           faire de test de validité
59       """
60       if self.parent.modified == 'n' : self.parent.init_modif()
61       if name != None:
62           valeur =name
63       else :
64           valeur= self.entry.get()
65           self.entry.delete(0,END)
66       self.node.item.set_valeur(valeur,evaluation='non')
67       self.parent.appli.affiche_infos(mess)
68       if self.node.item.get_position()=='global':
69           self.node.etape.verif_all()
70       elif self.node.item.get_position()=='global_jdc':
71           self.node.racine.verif_all()
72       else :
73           self.node.parent.verif()
74       self.node.update()
75       if self.node.item.isvalid():
76           self.node.parent.select()
77 # ----------------------------------------------------------------------------------------
78 #   Méthodes utlisées pour la manipulation des items dans les listes de choix
79 # ----------------------------------------------------------------------------------------
80   def selectValeur(self,name):
81       self.selected_valeur = name
82
83   def deselectValeur(self,name):
84       self.selectValeur = None
85
86   def sup_valeur(self,name=None):
87       """
88       Supprime la valeur selectionnée de la liste des valeurs et la rajoute
89       à la liste des choix possibles
90       """
91       liste_valeurs = self.Liste_valeurs.get_liste()
92       liste_valeurs.remove(self.selected_valeur)
93       liste_choix = self.node.item.get_definition().into
94       liste_choix = substract_list(liste_choix,liste_valeurs)
95       self.Liste_valeurs.put_liste(liste_valeurs)
96       self.Liste_choix.put_liste(liste_choix)
97       self.selected_valeur = None
98
99   def add_choix(self,name=None):
100       """
101       Ajoute le choix selectionné à la liste des valeurs et le retire
102       de la liste des choix possibles
103       """
104       min,max = self.node.item.GetMinMax()
105       liste_valeurs = self.Liste_valeurs.get_liste()
106       if len(liste_valeurs) >= max :
107           self.parent.appli.affiche_infos("La liste ne peut pas avoir plus de %d éléments" %max)
108           return
109       liste_valeurs.append(self.selected_choix)
110       liste_choix = self.Liste_choix.get_liste()
111       liste_choix.remove(self.selected_choix)
112       self.Liste_valeurs.put_liste(liste_valeurs)
113       self.Liste_choix.put_liste(liste_choix)
114       self.selected_choix = None
115
116   def selectChoix(self,name):
117       self.selected_choix = name
118
119   def deselectChoix(self,name):
120       self.selectChoix = None
121       
122 class SHELLPanel(newSIMPPanel):
123   """
124   Classe Panel utilisé pour les mots-clés simples qui attendent un shell pour valeur
125   """
126
127   def makeValeurPage(self,page):
128       """ 
129       Affiche la page concernant l'objet pointé par self qui attend un shell
130       """
131       objet_mc = self.node.item.get_definition()
132       aide = self.gen_aide()
133       aide = justify_text(texte=aide)
134       self.frame = Frame(page)
135       self.frame.place(relx=0,rely=0,relwidth=1,relheight=1)
136       label_aide = Label(self.frame,text = aide)
137       label_aide.place(relx=0.5,rely=0.1,anchor='center')
138       self.text = Text(self.frame,bg='gray95')
139       self.text.place(relx=0.2,rely=0.2,relwidth=0.6,relheight=0.6)
140       but_val = Button(self.frame,text='Valider',command = self.valide_shell)
141       but_ann = Button(self.frame,text='Annuler',command = self.annule_shell)
142       but_val.place(relx=0.35,rely=0.9,anchor='center')
143       but_ann.place(relx=0.65,rely=0.9,anchor='center')
144       self.display_valeur()
145
146   def gen_aide(self):
147       """
148       Retourne une chaîne de caractères d'aide sur la valeur qu'attend l'objet
149       pointé par self
150       """
151       return "Un shell est attendu"
152     
153   def valide_shell(self,event=None):
154       """
155       Récupère la valeur saisie par l'utilisateur dans self.text
156       et la stocke dans l'objet MCSIMP courant
157       """
158       texte = self.text.get(1.0,END)
159       self.record_valeur(texte)
160
161   def annule_shell(self,event=None):
162       """
163       Annule toute saisie dans self.text
164       """
165       self.text.delete(0,END)
166
167   def display_valeur(self,val=None):
168       """
169       Affiche la valeur de l'objet pointé par self
170       """
171       if val != None :
172           valeur = val
173       else:
174           valeur = self.node.item.get_valeur()
175       if valeur == None : return
176       self.text.insert(END,valeur)
177
178 class PLUSIEURS_Panel(newSIMPPanel):
179   """
180   Classe virtuelle servant de classe mère à toutes celles définissant
181   un panneau pour un mot-clé simple qui attend une liste de valeurs
182   """
183   def accepte_modifs_valeur(self,min,max):
184       """
185       Méthode qui récupère la liste des valeurs donnée par l'utilisateur
186       et l'affecte au mot-clé courant.
187       """
188       l_valeurs = self.Liste_valeurs.get_liste()
189       longueur = len(l_valeurs)
190       if longueur < min or longueur > max :
191           self.parent.appli.affiche_infos("Valeur refusée : nombre d'éléments incorrect dans la liste")
192           return
193       if longueur > 1:
194          valeur = tuple(l_valeurs)
195       elif longueur == 1:
196          valeur = l_valeurs[0]
197       else:
198          valeur = None
199       self.parent.appli.affiche_infos("Valeur acceptée")
200       self.record_valeur(valeur)
201       if self.node.item.isvalid():
202           self.node.parent.select()
203       # fermeture de la fenêtre de sélection
204       if self.ajout_valeurs:
205           self.ajout_valeurs.quit()
206           
207   def annule_modifs_valeur(self):
208       """
209       RAZ de la liste des valeurs (annule toutes les valeurs saisies par l'utilisateur)
210       """
211       self.node.select()
212       # fermeture de la fenêtre de sélection
213       if self.ajout_valeurs:
214           self.ajout_valeurs.quit()
215           
216   def traite_reel(self,valeur):
217       """
218       Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
219       ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
220       ou un EVAL ...
221       """
222       valeur = string.strip(valeur)
223       liste_reels = self.node.item.get_sd_avant_du_bon_type()
224       if valeur in liste_reels:
225           return valeur
226       if len(valeur) >= 3 :
227           if valeur[0:4] == 'EVAL' :
228               # on a trouvé un EVAL --> on retourne directement la valeur
229               return valeur
230       if string.find(valeur,'.') == -1 :
231           # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
232           return valeur+'.'
233       else:
234           return valeur
235         
236   def add_valeur_sans_into(self,name=None):
237       """
238       Lit ce que l'utilisateur a saisi dans self.entry et cherche à
239       l'évaluer :
240       - si la valeur est acceptable, elle est ajoutée dans la liste des valeurs
241       - sinon elle est refusée
242       """
243       min,max = self.node.item.GetMinMax()
244       if name != None :
245           valeur = name
246       else:
247           valeur = self.get_valeur()
248       if self.node.item.wait_reel():
249           valeur = self.traite_reel(valeur)
250       if self.node.item.wait_geom():
251           val,test1 = valeur,1
252       else:
253           val,test1 = self.node.item.object.eval_valeur(valeur)
254       if test1 :
255           test2 = self.node.item.object.verif_type(val)
256           if test2 :
257               liste_valeurs = self.Liste_valeurs.get_liste()
258               if len(liste_valeurs) >= max :
259                   self.parent.appli.affiche_infos("La liste a déjà atteint le nombre maximum d'éléments, ajout refusé")
260                   self.erase_valeur()
261                   return
262               liste_valeurs.append(val)
263               self.Liste_valeurs.put_liste(liste_valeurs)
264               self.erase_valeur()
265               self.parent.appli.affiche_infos("Nouvelle valeur acceptée")
266           else:
267               self.parent.appli.affiche_infos("Valeur incorrecte : ajout à la liste refusé")
268       else:
269           print "impossible d'évaluer %s" %val
270           self.parent.appli.affiche_infos("Valeur incorrecte : ajout à la liste refusé")
271       #if self.node.item.isvalid():
272       #    self.node.parent.select()
273
274   def sup_valeur_sans_into(self,name=None):
275       """
276       Méthode qui sert à retirer de la liste des valeurs la valeur sélectionnée
277       """
278       liste_valeurs = self.Liste_valeurs.get_liste()
279       try:
280           liste_valeurs.remove(self.selected_valeur)
281       except:
282           # la valeur sélectionnée n'est pas dans la liste
283           return
284       self.Liste_valeurs.put_liste(liste_valeurs)
285       #self.display_valeur('')
286       self.display_valeur(self.selected_valeur)
287       self.selected_valeur = None      
288
289   def display_valeur(self,val=None):
290       """
291       Affiche la valeur passée en argument dans l'entry de saisie.
292       Par défaut affiche la valeur du mot-clé simple
293       """
294       if not val :
295           valeur = self.node.item.getval()
296       else:
297           valeur = val
298       self.entry.delete(0,END)
299       if not valeur : return
300       self.entry.insert(0,str(valeur))
301       
302             
303 class PLUSIEURS_INTO_Panel(PLUSIEURS_Panel):
304   """
305   Classe servant à définir le panneau permettant d'afficher et de saisir une
306   liste de valeurs à choisir parmi une liste discrètes de valeurs possibles
307   """
308   def makeValeurPage(self,page):
309       """
310       Génère la page de saisie de plusieurs valeurs parmi un ensemble discret
311       de possibles
312       """
313       self.ajout_valeurs = None
314       # On récupère la bulle d'aide du panneau, l'objet, min et max (cardinalité de la liste),
315       # la liste des choix et la liste des valeurs
316       bulle_aide=self.get_bulle_aide()
317       objet_mc = self.node.item.get_definition()
318       min,max = self.node.item.GetMinMax()
319       l_choix=list(objet_mc.into)
320       l_choix.sort()
321       l_valeurs = self.node.item.GetListeValeurs()
322       # remplissage du panneau
323       self.frame_valeurs = Frame(page)
324       self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
325       self.frame_boutons_fleches = Frame(page)
326       self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
327       self.frame_choix = Frame(page)
328       self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
329       self.frame_boutons = Frame(page)
330       self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
331       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
332                                  ("<Button-3>",self.deselectValeur),
333                                  ("<Double-Button-1>",self.sup_valeur))
334       liste_commandes_choix = (("<Button-1>",self.selectChoix),
335                                ("<Button-3>",self.deselectChoix),
336                                ("<Double-Button-1>",self.add_choix))
337       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
338                                       titre="Valeur(s) actuelle(s)")
339       self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
340                                     titre= "Valeurs possibles")
341       bouton_add = Button(self.frame_boutons_fleches,
342                           #text="<--",
343                           image = images.get_image('arrow_left'),
344                           command = self.add_choix)
345       bouton_sup = Button(self.frame_boutons_fleches,
346                           #text="-->",
347                           image = images.get_image('arrow_right'),
348                           command = self.sup_valeur)
349       bouton_accepter = Button(self.frame_boutons,
350                                text='Valider',
351                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
352       bouton_annuler = Button(self.frame_boutons,
353                               text = 'Annuler',
354                               command = self.annule_modifs_valeur)
355       bouton_add.place(relx=0.3,rely=0.35)
356       bouton_sup.place(relx=0.3,rely=0.65)
357       for but in (bouton_accepter,bouton_annuler):
358           but.pack(side='left',padx=5)
359       self.Liste_valeurs.affiche_liste()
360       self.Liste_choix.affiche_liste()
361       for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
362           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
363           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
364
365   def get_bulle_aide(self):
366       """
367       Retourne la bulle d'aide du panneau (affichée par clic droit)
368       """
369       return """Un clic sur une valeur des deux listes la sélectionne.
370       - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
371       dans la liste des valeurs que vous voulez affecter au mot-clé simple
372       - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
373       sélectionnée (elle apparaît alors à nouveau comme choix possible
374       dans la liste des choix à droite)
375       - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
376       au mot-clé simple courant
377       - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
378       avant toute modification depuis le dernier 'Valider'"""
379
380 class PLUSIEURS_BASE_Panel(PLUSIEURS_Panel):
381   """
382   Classe définissant le panel associé aux mots-clés qui demandent
383   à l'utilisateur de donner une liste de valeurs qui ne sont pas
384   à choisir dans une liste discrètes et qui sont de type de base :
385   entier, réel, string,...
386   """
387   def makeValeurPage(self,page):
388       """
389       Crée la page de saisie d'une liste de valeurs à priori quelconques,
390       cad qui ne sont  pas à choisir dans une liste prédéfinie
391       """
392       # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
393       # et la liste des valeurs déjà affectées à l'objet courant
394       bulle_aide=self.get_bulle_aide()
395       objet_mc = self.node.item.get_definition()
396       aide = self.get_aide()
397       aide = justify_text(texte=aide)
398       min,max = self.node.item.GetMinMax()
399       l_valeurs = self.node.item.GetListeValeurs()
400       # création des frames globales
401       self.frame1 = Frame(page,relief='groove',bd=2)
402       self.frame2 = Frame(page)
403       self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.85)
404       self.frame2.place(relx=0.,rely=0.85,relwidth=1,relheight=0.15)
405       self.frame_right = Frame(self.frame1)
406       self.frame_right.place(relx=0.35,rely=0.,relwidth=0.65,relheight=1.)
407       # création des frames internes
408       self.frame_valeurs = Frame(self.frame1)
409       self.frame_valeurs.place(relx=0.02,rely=0.05,relwidth=0.35,relheight=0.95)
410       self.frame_boutons_fleches = Frame(self.frame_right)
411       self.frame_boutons_fleches.place(relx=0.,rely=0.2,relwidth=0.2,relheight=0.5)
412       self.frame_choix = Frame(self.frame_right)
413       self.frame_choix.place(relx=0.2,rely=0.2,relwidth=0.7,relheight=0.5)
414       self.frame_aide = Frame(self.frame_right)
415       self.frame_aide.place(relx=0.1,rely=0.7,relwidth=0.8,relheight=0.3)
416       self.frame_boutons = Frame(self.frame2)
417       self.frame_boutons.place(relx=0.35,rely=0.,relwidth=0.3,relheight=1.)
418       for fram in (self.frame1,self.frame2,self.frame_right,self.frame_valeurs,
419                  self.frame_boutons_fleches,self.frame_choix,self.frame_aide,self.frame_boutons):
420           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
421           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
422       # création des objets dans les frames
423       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
424                                  ("<Button-3>",self.deselectValeur),
425                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
426       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
427                                       titre="Valeur(s) actuelle(s)")
428       # Création de l'entry ou de la liste des SD
429       self.label = Label(self.frame_choix,text="Valeur :")
430       self.make_entry(frame = self.frame_choix,command = self.add_valeur_sans_into)
431       self.label.place(relx=0.05,rely=0.5)
432       # Création d'un bouton "Importer ..." sur le panel.
433       bouton_valeurs_fichier = Button(self.frame_choix,
434                                       text="Importer ...",
435                                       command=self.select_in_file)
436       bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)
437       self.ajout_valeurs = None
438       # boutons Ajouter et Supprimer
439       bouton_add = Button(self.frame_boutons_fleches,
440                           image = images.get_image('arrow_left'),
441                           command = self.add_valeur_sans_into)
442       bouton_sup = Button(self.frame_boutons_fleches,
443                           image = images.get_image('arrow_right'),
444                           command = self.sup_valeur_sans_into)
445       bouton_add.place(relx=0.3,rely=0.35)
446       bouton_sup.place(relx=0.3,rely=0.65)
447       # affichage de l'aide
448       self.frame_aide.update()
449       self.aide = Label(self.frame_aide,
450                         text = aide,
451                         justify='center',
452                         anchor='center',
453                         wraplength=int(self.frame_aide.winfo_width()*0.8))
454       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
455       self.Liste_valeurs.affiche_liste()
456       # boutons Accepter et Annuler
457       bouton_accepter = Button(self.frame_boutons,
458                                text='Valider',
459                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
460       bouton_annuler = Button(self.frame_boutons,
461                               text = 'Annuler',
462                               command = self.annule_modifs_valeur)
463       for but in (bouton_accepter,bouton_annuler):
464           but.pack(side='left',padx=5)
465
466   def select_in_file(self):
467       """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
468       nom_fichier = askopenfilename(title="Choix fichier :")
469       if nom_fichier == "":
470           return
471       try:
472           f = open(nom_fichier, "rb")
473           selection_texte = f.read()
474           f.close()
475           self.ajout_valeurs = FenetreDeSelection(self, 
476                                                   self.node.item,
477                                                   self.parent.appli,
478                                                   titre="Sélection de valeurs",
479                                                   texte=selection_texte)
480       except:
481           traceback.print_exc()
482           showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
483           
484   def get_bulle_aide(self):
485       """
486       Retourne l'aide associée au panneau courant
487       """
488       return """Taper dans la boîte de saisie de droite la valeur que
489       vous voulez affecter au mot-clé simple.
490       - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
491       dans la liste des valeurs que vous voulez affecter au mot-clé simple
492       - Un clic sur une valeur de la liste la sélectionne
493       - Un clic sur la flèche droite ou un double-clic retire la valeur
494       sélectionnée de la liste
495       - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
496       au mot-clé simple
497       - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
498       depuis le dernier clic sur 'Valider'"""
499
500   def get_aide(self):
501       """
502       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
503       que saisit l'utilisateur
504       """
505       mc = self.node.item.get_definition()
506       d_aides = { 'TXM' : 'chaînes de caractères',
507                   'R'   : 'réels',
508                   'I'   : 'entiers',
509                   'C'   : 'complexes'}
510       type = mc.type[0]
511       if not d_aides.has_key(type) : return 'Type de base inconnu'
512       if mc.min == mc.max:
513           return "Une liste de "+d_aides[type]+" chaînes de caractères est attendue"
514       else :
515           return "Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
516
517   def make_entry(self,frame,command):
518       """
519       Crée l'entry de saisie de la valeur souhaitée : distingue le
520       cas d'un complexe attendu, d'une autre valeur quelconque
521       """
522       if self.node.item.wait_complex():
523           self.typ_cplx=StringVar()
524           self.typ_cplx.set('RI')
525           rb1 = Radiobutton(frame, text='RI',variable=self.typ_cplx,value='RI')
526           rb2 = Radiobutton(frame, text='MP',variable=self.typ_cplx,value='MP')
527           self.entry1 = Pmw.EntryField(frame,validate='real')
528           self.entry2 = Pmw.EntryField(frame,validate='real')
529           rb1.place(relx=0.05,rely = 0.4)
530           rb2.place(relx=0.05,rely = 0.6)
531           self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus)
532           self.entry2.component('entry').bind("<Return>",lambda e,c=command:c())
533           self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
534           self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
535           self.entry1.focus()
536       else:
537           self.entry = Entry(frame,relief='sunken')
538           self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
539           self.entry.bind("<Return>",lambda e,c=command:c())
540           self.entry.focus()
541
542   def get_valeur(self):
543       """
544       Retourne la valeur saisie par l'utilisateur dans self.entry
545       """
546       return self.entry.get()
547
548   def erase_valeur(self):
549       """
550       Efface la valeur donnée par l'utilisateur dans l'entry
551       """
552       self.entry.delete(0,END)
553         
554 class PLUSIEURS_ASSD_Panel(PLUSIEURS_Panel):
555   """
556   Classe définissant le panel associé aux mots-clés qui demandent
557   à l'utilisateur de donner une liste de valeurs qui ne sont pas
558   à choisir dans une liste discrètes et qui sont de type dérivé d'ASSD
559   """
560   def makeValeurPage(self,page):
561       """
562       Génère la page de saisie de plusieurs noms de SD parmi un ensemble discret
563       de SD possibles, cad d'un type cohérent avec les types attendus par le mot-clé simple
564       """
565       # On récupère la bulle d'aide du panneau, l'objet, l'aide, min et max (cardinalité de la liste),
566       # la liste des valeurs déjà affectées à l'objet courant et la liste des SD du bon type
567       bulle_aide=self.get_bulle_aide()
568       self.ajout_valeurs=None
569       objet_mc = self.node.item.get_definition()
570       aide = self.get_aide()
571       aide = justify_text(texte=aide)
572       min,max = self.node.item.GetMinMax()
573       l_valeurs = self.node.item.GetListeValeurs()
574       l_choix=self.node.item.get_sd_avant_du_bon_type()
575       l_choix.sort()
576       # remplissage du panneau
577       self.frame_valeurs = Frame(page)
578       self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
579       self.frame_boutons_fleches = Frame(page)
580       self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
581       self.frame_choix = Frame(page)
582       self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
583       self.frame_boutons = Frame(page)
584       self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
585       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
586                                  ("<Button-3>",self.deselectValeur),
587                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
588       liste_commandes_choix = (("<Button-1>",self.selectChoix),
589                                ("<Button-3>",self.deselectChoix),
590                                ("<Double-Button-1>",self.add_valeur_sans_into))
591       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
592                                       titre="Valeur(s) actuelle(s)")
593       self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
594                                     titre= "Valeurs possibles")
595       bouton_add = Button(self.frame_boutons_fleches,
596                           #text="<--",
597                           image = images.get_image('arrow_left'),
598                           command = self.add_valeur_sans_into)
599       bouton_sup = Button(self.frame_boutons_fleches,
600                           #text="-->",
601                           image = images.get_image('arrow_right'),
602                           command = self.sup_valeur_sans_into)
603       bouton_accepter = Button(self.frame_boutons,
604                                text='Valider',
605                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
606       bouton_annuler = Button(self.frame_boutons,
607                               text = 'Annuler',
608                               command = self.annule_modifs_valeur)
609       bouton_add.place(relx=0.3,rely=0.35)
610       bouton_sup.place(relx=0.3,rely=0.65)
611       for but in (bouton_accepter,bouton_annuler):
612           but.pack(side='left',padx=5)
613       self.Liste_valeurs.affiche_liste()
614       self.Liste_choix.affiche_liste()
615       for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
616           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
617           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
618
619   def get_bulle_aide(self):
620       """
621       Retourne la bulle d'aide associée au panneau
622       """
623       return """Un clic sur une valeur des deux listes la sélectionne.
624       - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
625       dans la liste des valeurs que vous voulez affecter au mot-clé simple
626       - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
627       sélectionnée (elle apparaît alors à nouveau comme choix possible
628       dans la liste des choix à droite)
629       - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
630       au mot-clé simple courant
631       - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
632       avant toute modification depuis le dernier 'Valider'"""
633
634   def get_aide(self):
635       """
636       Retourne la phrase d'aide indiquant de quel type doivent être les
637       valeurs que doit entrer l'utilisateur
638       """
639       mc = self.node.item.get_definition()
640       type = mc.type[0].__name__  
641       if len(mc.type)>1 :
642           for typ in mc.type[1:] :
643               type = type + ' ou '+typ.__name__
644       if mc.min == mc.max:
645         return "Une liste de "+`mc.min`+" objets de type "+type+" est attendue"
646       else :
647         return "Une liste d'objets de type "+type+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
648     
649   def sup_valeur(self,name=None):
650       """
651       Supprime la valeur selectionnée de la liste des valeurs et la rajoute
652       à la liste des choix possibles
653       """
654       liste_valeurs = self.Liste_valeurs.get_liste()
655       liste_valeurs.remove(self.selected_valeur)
656       liste_choix = self.node.item.get_definition().into
657       liste_choix = substract_list(liste_choix,liste_valeurs)
658       self.Liste_valeurs.put_liste(liste_valeurs)
659       self.Liste_choix.put_liste(liste_choix)
660       self.selected_valeur = None      
661     
662   def erase_valeur(self):
663       pass
664
665   def get_valeur(self):
666       """
667       Retourne la valeur sélectionnée dans la liste des choix
668       """
669       return self.selected_choix
670
671   def display_valeur(self,val=None):
672       """
673          Affiche la valeur passée en argument dans l'entry de saisie.
674          Par défaut affiche la valeur du mot-clé simple
675       """
676       # Il n'y a pas d'entry pour ce type de panneau
677       return
678
679     
680 class UNIQUE_Panel(newSIMPPanel):
681   """
682   Classe virtuelle servant de classe mère à toutes celles définissant un panneau
683   permettant l'affichage et la saisie d'une valeur unique pour le mot-clé simple
684   """
685
686   def erase_valeur(self):
687       """
688       Efface l'entry de saisie
689       """
690       self.entry.delete(0,END)
691
692   def get_valeur(self):
693       """
694       Retourne la valeur donnée par l'utilisateur
695       """
696       return self.entry.get()
697     
698   def valid_valeur(self):
699       """
700       Teste si la valeur fournie par l'utilisateur est une valeur permise :
701       - si oui, l'enregistre
702       - si non, restaure l'ancienne valeur
703       """
704       if self.parent.modified == 'n' : self.parent.init_modif()
705       valeur = self.get_valeur()
706       self.erase_valeur()
707       anc_val = self.node.item.get_valeur()
708       test = self.node.item.set_valeur(valeur)
709       if not test :
710           mess = "impossible d'évaluer : %s " %`valeur`
711           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
712       elif self.node.item.isvalid() :
713           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
714           if self.node.item.get_position()=='global':
715               self.node.etape.verif_all()
716           elif self.node.item.get_position()=='global_jdc':
717               self.node.racine.verif_all()
718           else :
719               self.node.parent.verif()
720           self.node.update()
721           self.node.parent.select()
722       else :
723           cr = self.node.item.get_cr()
724           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
725           self.record_valeur(anc_val,mess=mess)
726
727 class UNIQUE_INTO_Panel(UNIQUE_Panel):
728   """
729   Classe définissant le panel associé aux mots-clés qui demandent
730   à l'utilisateur de choisir une seule valeur parmi une liste de valeurs
731   discrètes
732   """
733   def makeValeurPage(self,page):
734       """
735       Génère la page de saisie d'une seule valeur parmi un ensemble
736       discret de possibles
737       """
738       # récupération de la bulle d'aide et de l'objet mc
739       bulle_aide=self.get_bulle_aide()
740       objet_mc = self.node.item.get_definition()
741       # remplissage du panel
742       self.frame_valeur = Frame(page)
743       self.frame_valeur.pack(fill='both',expand=1)
744       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
745       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
746       l_choix=list(objet_mc.into)
747       l_choix.sort()
748       self.label = Label(self.frame_valeur,text='Choisir une valeur :')
749       self.label.pack(side='top')
750       self.frame = Frame(page)
751       self.frame.place(relx=0.33,rely=0.2,relwidth=0.33,relheight=0.6)
752       liste_commandes = (("<Button-1>",self.selectChoix),
753                          ("<Button-3>",self.deselectChoix),
754                          ("<Double-Button-1>",self.record_valeur))
755       self.Liste_choix = ListeChoix(self,self.frame,l_choix,liste_commandes = liste_commandes,
756                                     titre="Valeurs possibles")
757       self.Liste_choix.affiche_liste()
758
759   def get_bulle_aide(self):
760       """
761       Retourne la bulle d'aide affectée au panneau courant (affichée par clic droit)
762       """
763       return """Double-cliquez sur la valeur désirée
764       pour valoriser le mot-clé simple courant"""
765
766 class UNIQUE_ASSD_Panel(UNIQUE_Panel):
767   """
768   Classe servant à définir le panneau associé aux objets qui attendent une valeur unique
769   d'un type dérivé d'ASSD
770   """
771   def makeValeurPage(self,page):
772       """
773           Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une 
774           SD de type dérivé d'ASSD
775       """
776       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
777       # et de la liste des SD du bon type (constituant la liste des choix)
778       bulle_aide=self.get_bulle_aide()
779       aide=self.get_aide()
780       aide= justify_text(texte=aide)
781       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
782       # Remplissage du panneau
783       self.valeur_choisie = StringVar()
784       self.valeur_choisie.set('')
785       self.frame_valeur = Frame(page)
786       self.frame_valeur.pack(fill='both',expand=1)
787       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
788       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
789       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
790                                          items=liste_noms_sd,
791                                          labelpos='n',
792                                          label_text="Structures de données du type\n requis par l'objet courant :",
793                                          listbox_height = 6,
794                                          selectioncommand=self.select_valeur_from_list,
795                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
796       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
797       Label(self.frame_valeur,text='Structure de donnée choisie :').place(relx=0.05,rely=0.6)
798       #self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
799       Label(self.frame_valeur,textvariable=self.valeur_choisie).place(relx=0.5,rely=0.6)
800       # affichage de la valeur courante
801       self.display_valeur()
802
803   def get_bulle_aide(self):
804       """
805       Retourne l'aide associée au panneau
806       """
807       return "Double-cliquez sur la structure de donnée désirée pour valoriser le mot-clé simple courant"
808
809   def get_aide(self):
810       """
811       Retourne la phrase d'aide indiquant de quel type doit être la valeur à donner par l'utilisateur
812       """
813       mc = self.node.item.get_definition()
814       type = mc.type[0].__name__  
815       if len(mc.type)>1 :
816           for typ in mc.type[1:] :
817               type = type + ' ou '+typ.__name__
818       return  "Un objet de type "+type+" est attendu"
819     
820   def select_valeur_from_list(self):
821       """
822       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
823       """
824       if len(self.listbox.get()) == 0 : return
825       choix = self.listbox.getcurselection()[0]
826       self.valeur_choisie.set(choix)
827
828   def choose_valeur_from_list(self,command):
829       """
830       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
831       Exécute command
832       """
833       if len(self.listbox.get()) == 0 : return
834       choix = self.listbox.getcurselection()[0]
835       self.valeur_choisie.set(choix)
836       apply(command,(),{})
837
838   def get_valeur(self):
839       """
840       Retourne la valeur donnée par l'utilisateur au MCS
841       """
842       return self.valeur_choisie.get()
843     
844   def display_valeur(self):
845       """
846       Affiche la valeur de l'objet pointé par self
847       """
848       valeur = self.node.item.get_valeur()
849       if valeur == None : return # pas de valeur à afficher ...
850       self.valeur_choisie.set(valeur.nom)
851
852   def erase_valeur(self):
853       pass
854
855 class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel):
856   """
857   Classe servant à définir le panneau correspondant à un mot-clé simple
858   qui attend une valeur unique de type dérivé d'ASSD ou non encore
859   existante (type CO(...) utilisé dans les macros uniquement)
860   """
861   def makeValeurPage(self,page):
862       """
863       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une SD de type dérivé
864       d'ASSD
865       """
866       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
867       # et de la liste des SD du bon type (constituant la liste des choix)
868       bulle_aide=self.get_bulle_aide()
869       aide=self.get_aide()
870       aide= justify_text(texte=aide)
871       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
872       # Remplissage du panneau
873       self.frame_valeur = Frame(page)
874       self.frame_valeur.pack(fill='both',expand=1)
875       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
876       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
877       # affichage de la liste des SD existantes et du bon type
878       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
879                                          items=liste_noms_sd,
880                                          labelpos='n',
881                                          label_text="Structures de données du type\n requis par l'objet courant :",
882                                          listbox_height = 6,
883                                          selectioncommand=self.select_valeur_from_list,
884                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
885       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
886       # affichage du bouton 'Nouveau concept'
887       self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ",
888                                  items = ('NON','OUI'),menubutton_width=10)
889       self.b_co.configure(command = lambda e,s=self : s.ask_new_concept())
890       self.b_co.place(relx=0.05,rely=0.6,anchor='w')
891       self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :')
892       self.entry_co = Entry(self.frame_valeur)
893       self.entry_co.bind('<Return>',self.valid_nom_concept_co)
894       # affichage du label de la structure de donnée choisie
895       self.l_resu = Label(self.frame_valeur,text='Structure de donnée choisie :')
896       self.valeur_choisie = StringVar()
897       self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
898       self.frame_valeur.update()
899       self.aide = Label(self.frame_valeur,
900                         text = aide,
901                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
902                         justify='center')
903       self.aide.place(relx=0.5,rely=0.85,anchor='n')
904       # affichage de la valeur courante
905       self.display_valeur()
906       
907   def get_bulle_aide(self):
908       """
909       Retourne la bulle d'aide du panneau
910       """
911       return """Double-cliquez sur la structure de donnée désirée
912       pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour
913       entrer le nom d'un concept non encore existant"""
914
915   def valid_valeur(self):
916       """
917       Teste si la valeur fournie par l'utilisateur est une valeur permise :
918       - si oui, l'enregistre
919       - si non, restaure l'ancienne valeur
920       """
921       if self.parent.modified == 'n' : self.parent.init_modif()
922       valeur = self.get_valeur()
923       self.erase_valeur()
924       anc_val = self.node.item.get_valeur()
925       test_CO=self.node.item.is_CO(anc_val)
926       test = self.node.item.set_valeur(valeur)
927       if not test :
928           mess = "impossible d'évaluer : %s " %`valeur`
929           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
930           return
931       elif self.node.item.isvalid() :
932           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
933           if test_CO:
934              # il faut egalement propager la destruction de l'ancien concept
935              self.node.item.delete_valeur_co(valeur=anc_val)
936              # et on force le recalcul des concepts de sortie de l'etape
937              self.node.item.object.etape.get_type_produit(force=1)
938              # et le recalcul du contexte
939              self.node.item.object.etape.parent.reset_context()
940           self.node.parent.select()
941       else :
942           cr = self.node.item.get_cr()
943           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
944           self.record_valeur(anc_val,mess=mess)
945           return
946       if self.node.item.get_position()=='global':
947           self.node.etape.verif_all()
948       elif self.node.item.get_position()=='global_jdc':
949           self.node.racine.verif_all()
950       else :
951           self.node.parent.verif()
952       self.node.update()
953
954   def valid_nom_concept_co(self,event=None):
955       """
956       Lit le nom donné par l'utilisateur au concept de type CO qui doit être
957       la valeur du MCS courant et stocke cette valeur
958       """
959       if self.parent.modified == 'n' : self.parent.init_modif()
960       anc_val = self.node.item.get_valeur()
961       nom_concept = self.entry_co.get()
962       test,mess=self.node.item.set_valeur_co(nom_concept)
963       if not test:
964           # On n'a pas pu créer le concept
965           self.parent.appli.affiche_infos(mess)
966           return
967       elif self.node.item.isvalid() :
968           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
969           self.node.parent.select()
970       else :
971           cr = self.node.item.get_cr()
972           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
973           self.record_valeur(anc_val,mess=mess)
974           return
975       if self.node.item.get_position()=='global':
976           self.node.etape.verif_all()
977       elif self.node.item.get_position()=='global_jdc':
978           self.node.racine.verif_all()
979       else :
980           self.node.parent.verif()
981       if self.node.item.isvalid():
982           self.node.parent.select()
983       self.node.update()
984
985   def ask_new_concept(self):
986       """
987       Crée une entry dans le panneau d'un MCS qui attend un concept OU un CO() afin de
988       permettre à l'utilisateur de donner le nom du nouveau concept
989       """
990       new_concept = self.b_co.getcurselection()
991       if new_concept == 'OUI':
992           self.label_co.place(relx=0.05,rely=0.7)
993           self.entry_co.place(relx=0.45,rely=0.7,relwidth=0.25)
994           self.l_resu.place_forget()
995           self.label_valeur.place_forget()
996           self.entry_co.focus()
997       elif new_concept == 'NON':
998           # On est passe de OUI à NON, on supprime la valeur
999           self.node.item.delete_valeur_co()
1000           self.record_valeur(name=None,mess="Suppression CO enregistrée")
1001           self.label_co.place_forget()
1002           self.entry_co.place_forget()
1003           self.l_resu.place(relx=0.05,rely=0.7)
1004           self.label_valeur.place(relx=0.45,rely=0.7)
1005           
1006   def display_valeur(self):
1007       """
1008       Affiche la valeur de l'objet pointé par self
1009       """
1010       valeur = self.node.item.get_valeur()
1011       if valeur == None or valeur == '': 
1012          self.valeur_choisie.set('')
1013          return # pas de valeur à afficher ...
1014       # il faut configurer le bouton si la valeur est un objet CO
1015       # sinon afficher le nom du concept dans self.valeur_choisie
1016       if self.node.item.is_CO():
1017           self.b_co.invoke('OUI')
1018           self.entry_co.insert(0,valeur.nom)
1019       else:
1020           self.valeur_choisie.set(valeur.nom)
1021
1022   def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
1023       """
1024       Enregistre  val comme valeur de self.node.item.object SANS faire de test de validité
1025       """
1026       if self.parent.modified == 'n' : self.parent.init_modif()
1027       if name != None:
1028           valeur =name
1029       else :
1030           self.entry_co.delete(0,END)
1031           valeur= self.entry_co.get()
1032       self.node.item.set_valeur_co(valeur)
1033       self.parent.appli.affiche_infos(mess)
1034       # On met a jour le display dans le panneau
1035       self.display_valeur()
1036       if self.node.item.get_position()=='global':
1037           self.node.etape.verif_all()
1038       elif self.node.item.get_position()=='global_jdc':
1039           self.node.racine.verif_all()
1040       else :
1041           self.node.parent.verif()
1042       if self.node.item.isvalid():
1043           self.node.parent.select()
1044       self.node.update()
1045
1046
1047 class UNIQUE_BASE_Panel(UNIQUE_Panel):
1048   """
1049   Classe servant à définir le panneau associé aux mots-clés simples qui attendent
1050   une valeur d'un type de base (entier, réel ou string).
1051   """
1052   def makeValeurPage(self,page):
1053       """
1054       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1055       de base cad entier, réel, string ou complexe
1056       """
1057       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
1058       # et de la liste des SD du bon type (constituant la liste des choix)
1059       bulle_aide=self.get_bulle_aide()
1060       aide=self.get_aide()
1061       aide= justify_text(texte=aide)
1062       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
1063       # Remplissage du panneau
1064       self.frame_valeur = Frame(page)
1065       self.frame_valeur.pack(fill='both',expand=1)
1066       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1067       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1068       self.label = Label(self.frame_valeur,text='Valeur :')
1069       self.label.place(relx=0.1,rely=0.5)
1070       self.entry = Entry(self.frame_valeur,relief='sunken')
1071       self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
1072       self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
1073       self.entry.focus()
1074       # aide associée au panneau
1075       self.frame_valeur.update()
1076       self.aide = Label(self.frame_valeur, 
1077                         text = aide,
1078                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1079                         justify='center')
1080       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1081       # affichage de la valeur du MCS
1082       self.display_valeur()
1083
1084   def get_aide(self):
1085       """
1086       Retourne la phrase d'aide indiquant de quel type doit être la valeur
1087       du mot-clé simple fournie par l'utilisateur
1088       """
1089       mc = self.node.item.get_definition()
1090       d_aides = { 'TXM' : "Une chaîne de caractères est attendue",
1091                   'R'   : "Un réel est attendu",
1092                   'I'   : "Un entier est attendu"}
1093       type = mc.type[0]
1094       return d_aides.get(type,"Type de base inconnu")
1095
1096   def get_bulle_aide(self):
1097       """
1098       Retourne la bulle d'aide associée au panneau et affichée par clic droit
1099       """
1100       return """Saisissez la valeur que vous voulez affecter au mot-clé simple
1101       dans la zone de saisie et pressez <Return>"""
1102       
1103   def display_valeur(self):
1104       """
1105       Affiche la valeur de l'objet pointé par self
1106       """
1107       valeur = self.node.item.get_valeur()
1108       if valeur == None : return # pas de valeur à afficher ...
1109       self.entry.delete(0,END)
1110       self.entry.insert(0,valeur)
1111       
1112 class UNIQUE_COMP_Panel(UNIQUE_Panel):
1113   """
1114   Classe servant à définir le panneau associé aux mots-clés simples
1115   qui attendent une valeur de type complexe
1116   """
1117   def makeValeurPage(self,page):
1118       """
1119       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1120       de base cad entier, réel, string ou complexe
1121       """
1122       # Récupération de l'aide associée au panneau et de l'aide destinée à l'utilisateur
1123       bulle_aide=self.get_bulle_aide()
1124       aide=self.get_aide()
1125       aide= justify_text(texte=aide)
1126       # Remplissage du panneau
1127       self.frame_valeur = Frame(page)
1128       self.frame_valeur.pack(fill='both',expand=1)
1129       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1130       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1131       self.label = Label(self.frame_valeur,text='Valeur :')
1132       self.label.place(relx=0.1,rely=0.5)
1133       self.typ_cplx=StringVar()
1134       self.typ_cplx.set('RI')
1135       rb1 = Radiobutton(self.frame_valeur, text='RI',variable=self.typ_cplx,value='RI')
1136       rb2 = Radiobutton(self.frame_valeur, text='MP',variable=self.typ_cplx,value='MP')
1137       self.entry1 = Pmw.EntryField(self.frame_valeur,validate='real')
1138       self.entry2 = Pmw.EntryField(self.frame_valeur,validate='real')
1139       rb1.place(relx=0.05,rely = 0.4)
1140       rb2.place(relx=0.05,rely = 0.6)
1141       self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus())
1142       self.entry2.component('entry').bind("<Return>",lambda e,c=self.valid_valeur:c())
1143       self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
1144       self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
1145       self.entry1.focus()
1146       self.frame_valeur.update()
1147       self.aide = Label(self.frame_valeur,
1148                         text = aide,
1149                         wraplength=int(self.frame_valeur.winfo_width()*0.8),
1150                         justify='center')
1151       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1152
1153   def get_bulle_aide(self):
1154       """
1155       Retourne la bulle d'aide du panneau
1156       """
1157       return """-Choisissez votre format de saisie du complexe :
1158       \t 'RI' = parties réelle et imaginaire
1159       \t 'MP' = module/phase (en degrés)
1160       - Saisissez ensuite dans les deux zones de saisie les deux nombres attendus"""
1161
1162   def get_aide(self):
1163       """
1164       Retourne la phrase d'aide décrivant le type de la valeur que peut prendre
1165       le mot-clé simple courant
1166       """
1167       return 'Un complexe est attendu'
1168
1169   def get_valeur(self):
1170       """
1171       Retourne le complexe saisi par l'utilisateur
1172       """
1173       l=[]
1174       l.append(self.typ_cplx.get())
1175       l.append(string.atof(self.entry1.get()))
1176       l.append(string.atof(self.entry2.get()))
1177       return `tuple(l)`
1178
1179   def erase_valeur(self):
1180       """
1181       Efface les entries de saisie
1182       """
1183       self.typ_cplx = 'RI'
1184       self.entry1.delete(0,END)
1185       self.entry2.delete(0,END)
1186       
1187 class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
1188   panel = newSIMPPanel
1189
1190   def init(self) :
1191       self.expandable = 0
1192       self.affect_panel()
1193
1194   def affect_panel(self):
1195       """
1196       Cette méthode attribue le panel à l'objet pointé par self en fonction de la
1197       nature de la valeur demandée pour cet objet
1198       """
1199       if self.wait_shell():
1200           # l'objet attend un shell
1201           self.panel = SHELLPanel
1202       elif self.wait_into():
1203           # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
1204           min,max = self.GetMinMax()
1205           if max != 1 and ((min != 0 and min != max) or (min == 0)):
1206              # l'objet attend une liste de valeurs
1207              self.panel = PLUSIEURS_INTO_Panel
1208           else:
1209              # l'objet n'attend qu'une seule valeur
1210              self.panel = UNIQUE_INTO_Panel
1211       else:
1212           # l'objet prend une ou des valeurs à priori quelconques
1213           min,max = self.GetMinMax()
1214           if max != 1 :
1215               # on attend une liste de valeurs mais de quel type ?
1216               if self.wait_assd():
1217                   # on attend une liste de SD
1218                   self.panel = PLUSIEURS_ASSD_Panel
1219               else:
1220                   # on attend une liste de valeurs de types debase (entiers, réels,...)
1221                   self.panel = PLUSIEURS_BASE_Panel
1222           else:
1223               # on n'attend qu'une seule valeur mais de quel type ?
1224               if self.wait_co():
1225                   # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
1226                   self.panel = UNIQUE_SDCO_Panel
1227               elif self.wait_assd():
1228                   # on attend une SD
1229                   self.panel = UNIQUE_ASSD_Panel
1230               else:
1231                   # on attend une valeur d'un type de base (entier,réel,...)
1232                   if self.wait_complex():
1233                       # on attend un complexe
1234                       self.panel = UNIQUE_COMP_Panel
1235                   else:
1236                       # on attend un entier, un réel ou une string
1237                       self.panel = UNIQUE_BASE_Panel
1238       
1239   def SetText(self, text):
1240     try:
1241       value = eval(text)
1242       self.object.setval(value)
1243     except:
1244       pass
1245
1246   def GetIconName(self):
1247     if self.isvalid():
1248       return "ast-green-ball"
1249     elif self.object.isoblig():
1250       return "ast-red-ball"
1251     else:
1252       return "ast-yel-ball"
1253
1254   def GetText(self):
1255     """
1256     Classe SIMPTreeItem
1257     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
1258     pointé par self 
1259     """
1260     return self.object.GetText()
1261
1262   def wait_co(self):
1263       """
1264       Méthode booléenne qui retourne 1 si l'objet pointé par self
1265       attend un objet de type ASSD qui n'existe pas encore (type CO()),
1266       0 sinon
1267       """
1268       return self.object.wait_co()
1269
1270   def wait_geom(self):
1271       """
1272       Méthode booléenne qui retourne 1 si l'objet pointé par self
1273       attend un objet GEOM, 0 sinon
1274       """
1275       return self.object.wait_geom()
1276     
1277   def wait_complex(self):
1278       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1279       attend un complexe, 0 sinon """
1280       if 'C' in self.object.definition.type:
1281           return 1
1282       else:
1283           return 0
1284
1285   def wait_reel(self):
1286       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1287       attend un réel, 0 sinon """
1288       if 'R' in self.object.definition.type:
1289           return 1
1290       else:
1291           return 0
1292         
1293   def wait_shell(self):
1294       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1295       attend un shell, 0 sinon """
1296       if 'shell' in self.object.definition.type:
1297           return 1
1298       else:
1299           return 0
1300
1301   def wait_into(self):
1302       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1303       prend ses valeurs dans un ensemble discret (into), 0 sinon """
1304       if self.object.definition.into != None :
1305           return 1
1306       else:
1307           return 0
1308
1309   def wait_assd(self):
1310       """Méthode booléenne qui retourne 1 si l'objet pointé par self
1311       attend un objet de type ASSD ou dérivé, 0 sinon """
1312       return self.object.wait_assd()
1313     
1314   def getval(self):
1315       return self.object.getval()
1316     
1317   def GetMinMax(self):
1318       """ Retourne les valeurs min et max de la définition de object """
1319       return self.object.get_min_max()
1320
1321   def GetMultiplicite(self):
1322       """ A préciser.
1323           Retourne la multiplicité des valeurs affectées à l'objet
1324           représenté par l'item. Pour le moment retourne invariablement 1.
1325       """
1326       return 1
1327
1328   def GetType(self):
1329       """ 
1330           Retourne le type de valeur attendu par l'objet représenté par l'item.
1331       """
1332       return self.object.get_type()
1333
1334   def GetIntervalle(self):
1335       """ 
1336            Retourne le domaine de valeur attendu par l'objet représenté 
1337            par l'item.
1338       """
1339       return self.object.getintervalle()
1340
1341   def IsInIntervalle(self,valeur):
1342       """ 
1343           Retourne 1 si la valeur est dans l'intervalle permis par
1344           l'objet représenté par l'item.
1345       """
1346       return self.object.isinintervalle(valeur)
1347
1348   def set_valeur_co(self,nom_co):
1349       """
1350       Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
1351       """
1352       return self.object.set_valeur_co(nom_co)
1353       
1354   def get_sd_avant_du_bon_type(self):
1355       """
1356       Retourne la liste des noms des SD présentes avant l'étape qui contient
1357       le MCS pointé par self et du type requis par ce MCS
1358       """
1359       return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
1360                                                                self.object.definition.type)
1361     
1362   def GetListeValeurs(self) :
1363       """ Retourne la liste des valeurs de object """
1364       return self.object.get_liste_valeurs()
1365     
1366   def verif(self):
1367       pass
1368
1369   def isvalid(self):
1370     return self.object.isvalid()
1371
1372   def eval_valeur(self,valeur):
1373       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
1374       de l'objet pointé par self :
1375         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
1376         - retourne 'valeur' (chaîne de caractères) sinon """
1377       return self.object.eval_valeur(valeur)
1378
1379   def is_CO(self,valeur=None):
1380       """
1381          Indique si valeur est un concept produit de la macro
1382          Cette méthode n'a de sens que pour un MCSIMP d'une MACRO
1383          Si valeur vaut None on teste la valeur du mot cle
1384       """
1385       # Pour savoir si un concept est un nouveau concept de macro
1386       # on regarde s'il est présent dans l'attribut sdprods de l'étape
1387       # ou si son nom de classe est CO.
1388       # Il faut faire les 2 tests car une macro non valide peut etre
1389       # dans un etat pas tres catholique avec des CO pas encore types
1390       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
1391       if not valeur:valeur=self.object.valeur
1392       if valeur in self.object.etape.sdprods:return 1
1393       if type(valeur) is not types.ClassType:return 0
1394       if valeur.__class__.__name__ == 'CO':return 1
1395       return 0
1396
1397   def delete_valeur_co(self,valeur=None):
1398       """
1399            Supprime la valeur du mot cle (de type CO)
1400            il faut propager la destruction aux autres etapes
1401       """
1402       if not valeur : valeur=self.object.valeur
1403       # XXX faut il vraiment appeler del_sdprod ???
1404       #self.object.etape.parent.del_sdprod(valeur)
1405       self.object.etape.parent.delete_concept(valeur)
1406
1407 import Accas
1408 treeitem = SIMPTreeItem
1409 objet = Accas.MCSIMP
1410