]> SALOME platform Git repositories - tools/eficas.git/blob - Editeur/composimp.py
Salome HOME
F.R: recette modifs CCa : correction bug sur la copie et les
[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       if self.node.item.isvalid():
75           self.node.parent.select()
76       self.node.update()
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\r
204       if self.ajout_valeurs:\r
205           self.ajout_valeurs.quit()\r
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\r
213       if self.ajout_valeurs:\r
214           self.ajout_valeurs.quit()\r
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       """\r
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)\r
432       # Création d'un bouton "Importer ..." sur le panel.\r
433       bouton_valeurs_fichier = Button(self.frame_choix,\r
434                                       text="Importer ...",\r
435                                       command=self.select_in_file)\r
436       bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)\r
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.aide = Label(self.frame_aide,
449                         text = aide,
450                         justify='center',
451                         anchor='center')
452       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
453       self.Liste_valeurs.affiche_liste()
454       # boutons Accepter et Annuler
455       bouton_accepter = Button(self.frame_boutons,
456                                text='Valider',
457                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
458       bouton_annuler = Button(self.frame_boutons,
459                               text = 'Annuler',
460                               command = self.annule_modifs_valeur)
461       for but in (bouton_accepter,bouton_annuler):
462           but.pack(side='left',padx=5)
463 \r
464   def select_in_file(self):\r
465       """ Permet d'ouvrir un fichier choisi par l'utilisateur. """\r
466       nom_fichier = askopenfilename(title="Choix fichier :")\r
467       if nom_fichier == "":\r
468           return\r
469       try:\r
470           f = open(nom_fichier, "rb")\r
471           selection_texte = f.read()\r
472           f.close()\r
473           self.ajout_valeurs = FenetreDeSelection(self, self.node.item,\r
474                                          titre="Sélection de valeurs",\r
475                                          texte=selection_texte)\r
476       except:\r
477           showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)\r
478           
479   def get_bulle_aide(self):
480       """
481       Retourne l'aide associée au panneau courant
482       """
483       return """Taper dans la boîte de saisie de droite la valeur que
484       vous voulez affecter au mot-clé simple.
485       - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
486       dans la liste des valeurs que vous voulez affecter au mot-clé simple
487       - Un clic sur une valeur de la liste la sélectionne
488       - Un clic sur la flèche droite ou un double-clic retire la valeur
489       sélectionnée de la liste
490       - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
491       au mot-clé simple
492       - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
493       depuis le dernier clic sur 'Valider'"""
494
495   def get_aide(self):
496       """
497       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
498       que saisit l'utilisateur
499       """
500       mc = self.node.item.get_definition()
501       d_aides = { 'TXM' : 'chaînes de caractères',
502                   'R'   : 'réels',
503                   'I'   : 'entiers',
504                   'C'   : 'complexes'}
505       type = mc.type[0]
506       if not d_aides.has_key(type) : return 'Type de base inconnu'
507       if mc.min == mc.max:
508           return "Une liste de "+d_aides[type]+" chaînes de caractères est attendue"
509       else :
510           return "Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
511
512   def make_entry(self,frame,command):
513       """
514       Crée l'entry de saisie de la valeur souhaitée : distingue le
515       cas d'un complexe attendu, d'une autre valeur quelconque
516       """
517       if self.node.item.wait_complex():
518           self.typ_cplx=StringVar()
519           self.typ_cplx.set('RI')
520           rb1 = Radiobutton(frame, text='RI',variable=self.typ_cplx,value='RI')
521           rb2 = Radiobutton(frame, text='MP',variable=self.typ_cplx,value='MP')
522           self.entry1 = Pmw.EntryField(frame,validate='real')
523           self.entry2 = Pmw.EntryField(frame,validate='real')
524           rb1.place(relx=0.05,rely = 0.4)
525           rb2.place(relx=0.05,rely = 0.6)
526           self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus)
527           self.entry2.component('entry').bind("<Return>",lambda e,c=command:c())
528           self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
529           self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
530           self.entry1.focus()
531       else:
532           self.entry = Entry(frame,relief='sunken')
533           self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
534           self.entry.bind("<Return>",lambda e,c=command:c())
535           self.entry.focus()
536
537   def get_valeur(self):
538       """
539       Retourne la valeur saisie par l'utilisateur dans self.entry
540       """
541       return self.entry.get()
542
543   def erase_valeur(self):
544       """
545       Efface la valeur donnée par l'utilisateur dans l'entry
546       """
547       self.entry.delete(0,END)
548         
549 class PLUSIEURS_ASSD_Panel(PLUSIEURS_Panel):
550   """
551   Classe définissant le panel associé aux mots-clés qui demandent
552   à l'utilisateur de donner une liste de valeurs qui ne sont pas
553   à choisir dans une liste discrètes et qui sont de type dérivé d'ASSD
554   """
555   def makeValeurPage(self,page):
556       """
557       Génère la page de saisie de plusieurs noms de SD parmi un ensemble discret
558       de SD possibles, cad d'un type cohérent avec les types attendus par le mot-clé simple
559       """
560       # On récupère la bulle d'aide du panneau, l'objet, l'aide, min et max (cardinalité de la liste),
561       # la liste des valeurs déjà affectées à l'objet courant et la liste des SD du bon type
562       bulle_aide=self.get_bulle_aide()
563       self.ajout_valeurs=None
564       objet_mc = self.node.item.get_definition()
565       aide = self.get_aide()
566       aide = justify_text(texte=aide)
567       min,max = self.node.item.GetMinMax()
568       l_valeurs = self.node.item.GetListeValeurs()
569       l_choix=self.node.item.get_sd_avant_du_bon_type()
570       l_choix.sort()
571       # remplissage du panneau
572       self.frame_valeurs = Frame(page)
573       self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
574       self.frame_boutons_fleches = Frame(page)
575       self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
576       self.frame_choix = Frame(page)
577       self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
578       self.frame_boutons = Frame(page)
579       self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
580       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
581                                  ("<Button-3>",self.deselectValeur),
582                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
583       liste_commandes_choix = (("<Button-1>",self.selectChoix),
584                                ("<Button-3>",self.deselectChoix),
585                                ("<Double-Button-1>",self.add_valeur_sans_into))
586       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
587                                       titre="Valeur(s) actuelle(s)")
588       self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
589                                     titre= "Valeurs possibles")
590       bouton_add = Button(self.frame_boutons_fleches,
591                           #text="<--",
592                           image = images.get_image('arrow_left'),
593                           command = self.add_valeur_sans_into)
594       bouton_sup = Button(self.frame_boutons_fleches,
595                           #text="-->",
596                           image = images.get_image('arrow_right'),
597                           command = self.sup_valeur_sans_into)
598       bouton_accepter = Button(self.frame_boutons,
599                                text='Valider',
600                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
601       bouton_annuler = Button(self.frame_boutons,
602                               text = 'Annuler',
603                               command = self.annule_modifs_valeur)
604       bouton_add.place(relx=0.3,rely=0.35)
605       bouton_sup.place(relx=0.3,rely=0.65)
606       for but in (bouton_accepter,bouton_annuler):
607           but.pack(side='left',padx=5)
608       self.Liste_valeurs.affiche_liste()
609       self.Liste_choix.affiche_liste()
610       for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
611           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
612           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
613
614   def get_bulle_aide(self):
615       """
616       Retourne la bulle d'aide associée au panneau
617       """
618       return """Un clic sur une valeur des deux listes la sélectionne.
619       - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
620       dans la liste des valeurs que vous voulez affecter au mot-clé simple
621       - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
622       sélectionnée (elle apparaît alors à nouveau comme choix possible
623       dans la liste des choix à droite)
624       - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
625       au mot-clé simple courant
626       - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
627       avant toute modification depuis le dernier 'Valider'"""
628
629   def get_aide(self):
630       """
631       Retourne la phrase d'aide indiquant de quel type doivent être les
632       valeurs que doit entrer l'utilisateur
633       """
634       mc = self.node.item.get_definition()
635       type = mc.type[0].__name__  
636       if len(mc.type)>1 :
637           for typ in mc.type[1:] :
638               type = type + ' ou '+typ.__name__
639       if mc.min == mc.max:
640         return "Une liste de "+`mc.min`+" objets de type "+type+" est attendue"
641       else :
642         return "Une liste d'objets de type "+type+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
643     
644   def sup_valeur(self,name=None):
645       """
646       Supprime la valeur selectionnée de la liste des valeurs et la rajoute
647       à la liste des choix possibles
648       """
649       liste_valeurs = self.Liste_valeurs.get_liste()
650       liste_valeurs.remove(self.selected_valeur)
651       liste_choix = self.node.item.get_definition().into
652       liste_choix = substract_list(liste_choix,liste_valeurs)
653       self.Liste_valeurs.put_liste(liste_valeurs)
654       self.Liste_choix.put_liste(liste_choix)
655       self.selected_valeur = None      
656     
657   def erase_valeur(self):
658       pass
659
660   def get_valeur(self):
661       """
662       Retourne la valeur sélectionnée dans la liste des choix
663       """
664       return self.selected_choix
665
666   def display_valeur(self,val=None):
667       """
668          Affiche la valeur passée en argument dans l'entry de saisie.
669          Par défaut affiche la valeur du mot-clé simple
670       """
671       # Il n'y a pas d'entry pour ce type de panneau
672       return
673
674     
675 class UNIQUE_Panel(newSIMPPanel):
676   """
677   Classe virtuelle servant de classe mère à toutes celles définissant un panneau
678   permettant l'affichage et la saisie d'une valeur unique pour le mot-clé simple
679   """
680
681   def erase_valeur(self):
682       """
683       Efface l'entry de saisie
684       """
685       self.entry.delete(0,END)
686
687   def get_valeur(self):
688       """
689       Retourne la valeur donnée par l'utilisateur
690       """
691       return self.entry.get()
692     
693   def valid_valeur(self):
694       """
695       Teste si la valeur fournie par l'utilisateur est une valeur permise :
696       - si oui, l'enregistre
697       - si non, restaure l'ancienne valeur
698       """
699       if self.parent.modified == 'n' : self.parent.init_modif()
700       valeur = self.get_valeur()
701       self.erase_valeur()
702       anc_val = self.node.item.get_valeur()
703       test = self.node.item.set_valeur(valeur)
704       if not test :
705           mess = "impossible d'évaluer : %s " %`valeur`
706           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
707           return
708       elif self.node.item.isvalid() :
709           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
710           self.node.parent.select()
711       else :
712           cr = self.node.item.get_cr()
713           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
714           self.record_valeur(anc_val,mess=mess)
715           return
716       if self.node.item.get_position()=='global':
717           self.node.etape.verif_all()
718       elif self.node.item.get_position()=='global_jdc':
719           self.node.racine.verif_all()
720       else :
721           self.node.parent.verif()
722       self.node.update()
723
724 class UNIQUE_INTO_Panel(UNIQUE_Panel):
725   """
726   Classe définissant le panel associé aux mots-clés qui demandent
727   à l'utilisateur de choisir une seule valeur parmi une liste de valeurs
728   discrètes
729   """
730   def makeValeurPage(self,page):
731       """
732       Génère la page de saisie d'une seule valeur parmi un ensemble
733       discret de possibles
734       """
735       # récupération de la bulle d'aide et de l'objet mc
736       bulle_aide=self.get_bulle_aide()
737       objet_mc = self.node.item.get_definition()
738       # remplissage du panel
739       self.frame_valeur = Frame(page)
740       self.frame_valeur.pack(fill='both',expand=1)
741       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
742       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
743       l_choix=list(objet_mc.into)
744       l_choix.sort()
745       self.label = Label(self.frame_valeur,text='Choisir une valeur :')
746       self.label.pack(side='top')
747       self.frame = Frame(page)
748       self.frame.place(relx=0.33,rely=0.2,relwidth=0.33,relheight=0.6)
749       liste_commandes = (("<Button-1>",self.selectChoix),
750                          ("<Button-3>",self.deselectChoix),
751                          ("<Double-Button-1>",self.record_valeur))
752       self.Liste_choix = ListeChoix(self,self.frame,l_choix,liste_commandes = liste_commandes,
753                                     titre="Valeurs possibles")
754       self.Liste_choix.affiche_liste()
755
756   def get_bulle_aide(self):
757       """
758       Retourne la bulle d'aide affectée au panneau courant (affichée par clic droit)
759       """
760       return """Double-cliquez sur la valeur désirée
761       pour valoriser le mot-clé simple courant"""
762
763 class UNIQUE_ASSD_Panel(UNIQUE_Panel):
764   """
765   Classe servant à définir le panneau associé aux objets qui attendent une valeur unique
766   d'un type dérivé d'ASSD
767   """
768   def makeValeurPage(self,page):
769       """
770           Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une 
771           SD de type dérivé d'ASSD
772       """
773       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
774       # et de la liste des SD du bon type (constituant la liste des choix)
775       bulle_aide=self.get_bulle_aide()
776       aide=self.get_aide()
777       aide= justify_text(texte=aide)
778       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
779       # Remplissage du panneau
780       self.valeur_choisie = StringVar()
781       self.valeur_choisie.set('')
782       self.frame_valeur = Frame(page)
783       self.frame_valeur.pack(fill='both',expand=1)
784       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
785       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
786       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
787                                          items=liste_noms_sd,
788                                          labelpos='n',
789                                          label_text="Structures de données du type\n requis par l'objet courant :",
790                                          listbox_height = 6,
791                                          selectioncommand=self.select_valeur_from_list,
792                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
793       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
794       Label(self.frame_valeur,text='Structure de donnée choisie :').place(relx=0.05,rely=0.6)
795       #self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
796       Label(self.frame_valeur,textvariable=self.valeur_choisie).place(relx=0.5,rely=0.6)
797       # affichage de la valeur courante
798       self.display_valeur()
799
800   def get_bulle_aide(self):
801       """
802       Retourne l'aide associée au panneau
803       """
804       return "Double-cliquez sur la structure de donnée désirée pour valoriser le mot-clé simple courant"
805
806   def get_aide(self):
807       """
808       Retourne la phrase d'aide indiquant de quel type doit être la valeur à donner par l'utilisateur
809       """
810       mc = self.node.item.get_definition()
811       type = mc.type[0].__name__  
812       if len(mc.type)>1 :
813           for typ in mc.type[1:] :
814               type = type + ' ou '+typ.__name__
815       return  "Un objet de type "+type+" est attendu"
816     
817   def select_valeur_from_list(self):
818       """
819       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
820       """
821       if len(self.listbox.get()) == 0 : return
822       choix = self.listbox.getcurselection()[0]
823       self.valeur_choisie.set(choix)
824
825   def choose_valeur_from_list(self,command):
826       """
827       Affecte à valeur choisie la sélection courante dans la liste des choix proposée
828       Exécute command
829       """
830       if len(self.listbox.get()) == 0 : return
831       choix = self.listbox.getcurselection()[0]
832       self.valeur_choisie.set(choix)
833       apply(command,(),{})
834
835   def get_valeur(self):
836       """
837       Retourne la valeur donnée par l'utilisateur au MCS
838       """
839       return self.valeur_choisie.get()
840     
841   def display_valeur(self):
842       """
843       Affiche la valeur de l'objet pointé par self
844       """
845       valeur = self.node.item.get_valeur()
846       if valeur == None : return # pas de valeur à afficher ...
847       self.valeur_choisie.set(valeur.nom)
848
849   def erase_valeur(self):
850       pass
851
852 class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel):
853   """
854   Classe servant à définir le panneau correspondant à un mot-clé simple
855   qui attend une valeur unique de type dérivé d'ASSD ou non encore
856   existante (type CO(...) utilisé dans les macros uniquement)
857   """
858   def makeValeurPage(self,page):
859       """
860       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une SD de type dérivé
861       d'ASSD
862       """
863       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
864       # et de la liste des SD du bon type (constituant la liste des choix)
865       bulle_aide=self.get_bulle_aide()
866       aide=self.get_aide()
867       aide= justify_text(texte=aide)
868       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
869       # Remplissage du panneau
870       self.frame_valeur = Frame(page)
871       self.frame_valeur.pack(fill='both',expand=1)
872       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
873       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
874       # affichage de la liste des SD existantes et du bon type
875       self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
876                                          items=liste_noms_sd,
877                                          labelpos='n',
878                                          label_text="Structures de données du type\n requis par l'objet courant :",
879                                          listbox_height = 6,
880                                          selectioncommand=self.select_valeur_from_list,
881                                          dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
882       self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
883       # affichage du bouton 'Nouveau concept'
884       self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ",
885                                  items = ('NON','OUI'),menubutton_width=10)
886       self.b_co.configure(command = lambda e,s=self : s.ask_new_concept())
887       self.b_co.place(relx=0.05,rely=0.6,anchor='w')
888       self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :')
889       self.entry_co = Entry(self.frame_valeur)
890       self.entry_co.bind('<Return>',self.valid_nom_concept_co)
891       # affichage du label de la structure de donnée choisie
892       self.l_resu = Label(self.frame_valeur,text='Structure de donnée choisie :')
893       self.valeur_choisie = StringVar()
894       self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
895       self.aide = Label(self.frame_valeur, text = aide)
896       self.aide.place(relx=0.5,rely=0.85,anchor='n')
897       # affichage de la valeur courante
898       self.display_valeur()
899       
900   def get_bulle_aide(self):
901       """
902       Retourne la bulle d'aide du panneau
903       """
904       return """Double-cliquez sur la structure de donnée désirée
905       pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour
906       entrer le nom d'un concept non encore existant"""
907
908   def valid_valeur(self):
909       """
910       Teste si la valeur fournie par l'utilisateur est une valeur permise :
911       - si oui, l'enregistre
912       - si non, restaure l'ancienne valeur
913       """
914       if self.parent.modified == 'n' : self.parent.init_modif()
915       valeur = self.get_valeur()
916       self.erase_valeur()
917       anc_val = self.node.item.get_valeur()
918       test_CO=self.node.item.is_CO(anc_val)
919       test = self.node.item.set_valeur(valeur)
920       if not test :
921           mess = "impossible d'évaluer : %s " %`valeur`
922           self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
923           return
924       elif self.node.item.isvalid() :
925           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
926           if test_CO:
927              # il faut egalement propager la destruction de l'ancien concept
928              self.node.item.delete_valeur_co(valeur=anc_val)
929              # et on force le recalcul des concepts de sortie de l'etape
930              self.node.item.object.etape.get_type_produit(force=1)
931              # et le recalcul du contexte
932              self.node.item.object.etape.parent.reset_context()
933           self.node.parent.select()
934       else :
935           cr = self.node.item.get_cr()
936           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
937           self.record_valeur(anc_val,mess=mess)
938           return
939       if self.node.item.get_position()=='global':
940           self.node.etape.verif_all()
941       elif self.node.item.get_position()=='global_jdc':
942           self.node.racine.verif_all()
943       else :
944           self.node.parent.verif()
945       self.node.update()
946
947   def valid_nom_concept_co(self,event=None):
948       """
949       Lit le nom donné par l'utilisateur au concept de type CO qui doit être
950       la valeur du MCS courant et stocke cette valeur
951       """
952       if self.parent.modified == 'n' : self.parent.init_modif()
953       anc_val = self.node.item.get_valeur()
954       nom_concept = self.entry_co.get()
955       test,mess=self.node.item.set_valeur_co(nom_concept)
956       if not test:
957           # On n'a pas pu créer le concept
958           self.parent.appli.affiche_infos(mess)
959           return
960       elif self.node.item.isvalid() :
961           self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
962           self.node.parent.select()
963       else :
964           cr = self.node.item.get_cr()
965           mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
966           self.record_valeur(anc_val,mess=mess)
967           return
968       if self.node.item.get_position()=='global':
969           self.node.etape.verif_all()
970       elif self.node.item.get_position()=='global_jdc':
971           self.node.racine.verif_all()
972       else :
973           self.node.parent.verif()
974       if self.node.item.isvalid():
975           self.node.parent.select()
976       self.node.update()
977
978   def ask_new_concept(self):
979       """
980       Crée une entry dans le panneau d'un MCS qui attend un concept OU un CO() afin de
981       permettre à l'utilisateur de donner le nom du nouveau concept
982       """
983       new_concept = self.b_co.getcurselection()
984       if new_concept == 'OUI':
985           self.label_co.place(relx=0.05,rely=0.7)
986           self.entry_co.place(relx=0.45,rely=0.7,relwidth=0.25)
987           self.l_resu.place_forget()
988           self.label_valeur.place_forget()
989           self.entry_co.focus()
990       elif new_concept == 'NON':
991           # On est passe de OUI à NON, on supprime la valeur
992           self.node.item.delete_valeur_co()
993           self.record_valeur(name=None,mess="Suppression CO enregistrée")
994           self.label_co.place_forget()
995           self.entry_co.place_forget()
996           self.l_resu.place(relx=0.05,rely=0.7)
997           self.label_valeur.place(relx=0.45,rely=0.7)
998           
999   def display_valeur(self):
1000       """
1001       Affiche la valeur de l'objet pointé par self
1002       """
1003       valeur = self.node.item.get_valeur()
1004       if valeur == None or valeur == '': 
1005          self.valeur_choisie.set('')
1006          return # pas de valeur à afficher ...
1007       # il faut configurer le bouton si la valeur est un objet CO
1008       # sinon afficher le nom du concept dans self.valeur_choisie
1009       if self.node.item.is_CO():
1010           self.b_co.invoke('OUI')
1011           self.entry_co.insert(0,valeur.nom)
1012       else:
1013           self.valeur_choisie.set(valeur.nom)
1014
1015   def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
1016       """
1017       Enregistre  val comme valeur de self.node.item.object SANS faire de test de validité
1018       """
1019       if self.parent.modified == 'n' : self.parent.init_modif()
1020       if name != None:
1021           valeur =name
1022       else :
1023           self.entry_co.delete(0,END)
1024           valeur= self.entry_co.get()
1025       self.node.item.set_valeur_co(valeur)
1026       self.parent.appli.affiche_infos(mess)
1027       # On met a jour le display dans le panneau
1028       self.display_valeur()
1029       if self.node.item.get_position()=='global':
1030           self.node.etape.verif_all()
1031       elif self.node.item.get_position()=='global_jdc':
1032           self.node.racine.verif_all()
1033       else :
1034           self.node.parent.verif()
1035       if self.node.item.isvalid():
1036           self.node.parent.select()
1037       self.node.update()
1038
1039
1040 class UNIQUE_BASE_Panel(UNIQUE_Panel):
1041   """
1042   Classe servant à définir le panneau associé aux mots-clés simples qui attendent
1043   une valeur d'un type de base (entier, réel ou string).
1044   """
1045   def makeValeurPage(self,page):
1046       """
1047       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1048       de base cad entier, réel, string ou complexe
1049       """
1050       # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
1051       # et de la liste des SD du bon type (constituant la liste des choix)
1052       bulle_aide=self.get_bulle_aide()
1053       aide=self.get_aide()
1054       aide= justify_text(texte=aide)
1055       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
1056       # Remplissage du panneau
1057       self.frame_valeur = Frame(page)
1058       self.frame_valeur.pack(fill='both',expand=1)
1059       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1060       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1061       self.label = Label(self.frame_valeur,text='Valeur :')
1062       self.label.place(relx=0.1,rely=0.5)
1063       self.entry = Entry(self.frame_valeur,relief='sunken')
1064       self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
1065       self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
1066       self.entry.focus()
1067       # aide associée au panneau
1068       self.aide = Label(self.frame_valeur, text = aide)
1069       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1070       # affichage de la valeur du MCS
1071       self.display_valeur()
1072
1073   def get_aide(self):
1074       """
1075       Retourne la phrase d'aide indiquant de quel type doit être la valeur
1076       du mot-clé simple fournie par l'utilisateur
1077       """
1078       mc = self.node.item.get_definition()
1079       d_aides = { 'TXM' : "Une chaîne de caractères est attendue",
1080                   'R'   : "Un réel est attendu",
1081                   'I'   : "Un entier est attendu"}
1082       type = mc.type[0]
1083       return d_aides.get(type,"Type de base inconnu")
1084
1085   def get_bulle_aide(self):
1086       """
1087       Retourne la bulle d'aide associée au panneau et affichée par clic droit
1088       """
1089       return """Saisissez la valeur que vous voulez affecter au mot-clé simple
1090       dans la zone de saisie et pressez <Return>"""
1091       
1092   def display_valeur(self):
1093       """
1094       Affiche la valeur de l'objet pointé par self
1095       """
1096       valeur = self.node.item.get_valeur()
1097       if valeur == None : return # pas de valeur à afficher ...
1098       self.entry.delete(0,END)
1099       self.entry.insert(0,valeur)
1100       
1101 class UNIQUE_COMP_Panel(UNIQUE_Panel):
1102   """
1103   Classe servant à définir le panneau associé aux mots-clés simples
1104   qui attendent une valeur de type complexe
1105   """
1106   def makeValeurPage(self,page):
1107       """
1108       Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
1109       de base cad entier, réel, string ou complexe
1110       """
1111       # Récupération de l'aide associée au panneau et de l'aide destinée à l'utilisateur
1112       bulle_aide=self.get_bulle_aide()
1113       aide=self.get_aide()
1114       aide= justify_text(texte=aide)
1115       # Remplissage du panneau
1116       self.frame_valeur = Frame(page)
1117       self.frame_valeur.pack(fill='both',expand=1)
1118       self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
1119       self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
1120       self.label = Label(self.frame_valeur,text='Valeur :')
1121       self.label.place(relx=0.1,rely=0.5)
1122       self.typ_cplx=StringVar()
1123       self.typ_cplx.set('RI')
1124       rb1 = Radiobutton(self.frame_valeur, text='RI',variable=self.typ_cplx,value='RI')
1125       rb2 = Radiobutton(self.frame_valeur, text='MP',variable=self.typ_cplx,value='MP')
1126       self.entry1 = Pmw.EntryField(self.frame_valeur,validate='real')
1127       self.entry2 = Pmw.EntryField(self.frame_valeur,validate='real')
1128       rb1.place(relx=0.05,rely = 0.4)
1129       rb2.place(relx=0.05,rely = 0.6)
1130       self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus())
1131       self.entry2.component('entry').bind("<Return>",lambda e,c=self.valid_valeur:c())
1132       self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
1133       self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
1134       self.entry1.focus()
1135       self.aide = Label(self.frame_valeur, text = aide)
1136       self.aide.place(relx=0.5,rely=0.7,anchor='n')
1137
1138   def get_bulle_aide(self):
1139       """
1140       Retourne la bulle d'aide du panneau
1141       """
1142       return """-Choisissez votre format de saisie du complexe :
1143       \t 'RI' = parties réelle et imaginaire
1144       \t 'MP' = module/phase (en degrés)
1145       - Saisissez ensuite dans les deux zones de saisie les deux nombres attendus"""
1146
1147   def get_aide(self):
1148       """
1149       Retourne la phrase d'aide décrivant le type de la valeur que peut prendre
1150       le mot-clé simple courant
1151       """
1152       return 'Un complexe est attendu'
1153
1154   def get_valeur(self):
1155       """
1156       Retourne le complexe saisi par l'utilisateur
1157       """
1158       l=[]
1159       l.append(self.typ_cplx.get())
1160       l.append(string.atof(self.entry1.get()))
1161       l.append(string.atof(self.entry2.get()))
1162       return `tuple(l)`
1163
1164   def erase_valeur(self):
1165       """
1166       Efface les entries de saisie
1167       """
1168       self.typ_cplx = 'RI'
1169       self.entry1.delete(0,END)
1170       self.entry2.delete(0,END)
1171       
1172 class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
1173   panel = newSIMPPanel
1174
1175   def init(self) :
1176       self.expandable = 0
1177       self.affect_panel()
1178
1179   def affect_panel(self):
1180       """
1181       Cette méthode attribue le panel à l'objet pointé par self en fonction de la
1182       nature de la valeur demandée pour cet objet
1183       """
1184       if self.wait_shell():
1185           # l'objet attend un shell
1186           self.panel = SHELLPanel
1187       elif self.wait_into():
1188           # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
1189           min,max = self.GetMinMax()
1190           if max != 1 and ((min != 0 and min != max) or (min == 0)):
1191              # l'objet attend une liste de valeurs
1192              self.panel = PLUSIEURS_INTO_Panel
1193           else:
1194              # l'objet n'attend qu'une seule valeur
1195              self.panel = UNIQUE_INTO_Panel
1196       else:
1197           # l'objet prend une ou des valeurs à priori quelconques
1198           min,max = self.GetMinMax()
1199           if max != 1 :
1200               # on attend une liste de valeurs mais de quel type ?
1201               if self.wait_assd():
1202                   # on attend une liste de SD
1203                   self.panel = PLUSIEURS_ASSD_Panel
1204               else:
1205                   # on attend une liste de valeurs de types debase (entiers, réels,...)
1206                   self.panel = PLUSIEURS_BASE_Panel
1207           else:
1208               # on n'attend qu'une seule valeur mais de quel type ?
1209               if self.wait_co():
1210                   # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
1211                   self.panel = UNIQUE_SDCO_Panel
1212               elif self.wait_assd():
1213                   # on attend une SD
1214                   self.panel = UNIQUE_ASSD_Panel
1215               else:
1216                   # on attend une valeur d'un type de base (entier,réel,...)
1217                   if self.wait_complex():
1218                       # on attend un complexe
1219                       self.panel = UNIQUE_COMP_Panel
1220                   else:
1221                       # on attend un entier, un réel ou une string
1222                       self.panel = UNIQUE_BASE_Panel
1223       
1224   def SetText(self, text):
1225     try:
1226       value = eval(text)
1227       self.object.setval(value)
1228     except:
1229       pass
1230
1231   def GetIconName(self):
1232     if self.isvalid():
1233       return "ast-green-ball"
1234     elif self.object.isoblig():
1235       return "ast-red-ball"
1236     else:
1237       return "ast-yel-ball"
1238
1239   def GetText(self):
1240     """
1241     Classe SIMPTreeItem
1242     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
1243     pointé par self 
1244     """
1245     return self.object.GetText()
1246
1247   def wait_co(self):
1248       """
1249       Méthode booléenne qui retourne 1 si l'objet pointé par self
1250       attend un objet de type ASSD qui n'existe pas encore (type CO()),
1251       0 sinon
1252       """
1253       return self.object.wait_co()
1254
1255   def wait_geom(self):
1256       """
1257       Méthode booléenne qui retourne 1 si l'objet pointé par self
1258       attend un objet GEOM, 0 sinon
1259       """
1260       return self.object.wait_geom()
1261     
1262   def wait_complex(self):
1263       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1264       attend un complexe, 0 sinon """
1265       if 'C' in self.object.definition.type:
1266           return 1
1267       else:
1268           return 0
1269
1270   def wait_reel(self):
1271       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1272       attend un réel, 0 sinon """
1273       if 'R' in self.object.definition.type:
1274           return 1
1275       else:
1276           return 0
1277         
1278   def wait_shell(self):
1279       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1280       attend un shell, 0 sinon """
1281       if 'shell' in self.object.definition.type:
1282           return 1
1283       else:
1284           return 0
1285
1286   def wait_into(self):
1287       """ Méthode booléenne qui retourne 1 si l'objet pointé par self
1288       prend ses valeurs dans un ensemble discret (into), 0 sinon """
1289       if self.object.definition.into != None :
1290           return 1
1291       else:
1292           return 0
1293
1294   def wait_assd(self):
1295       """Méthode booléenne qui retourne 1 si l'objet pointé par self
1296       attend un objet de type ASSD ou dérivé, 0 sinon """
1297       return self.object.wait_assd()
1298     
1299   def getval(self):
1300       return self.object.getval()
1301     
1302   def GetMinMax(self):
1303       """ Retourne les valeurs min et max de la définition de object """
1304       return self.object.get_min_max()
1305
1306   def GetMultiplicite(self):
1307       """ A préciser.
1308           Retourne la multiplicité des valeurs affectées à l'objet
1309           représenté par l'item. Pour le moment retourne invariablement 1.
1310       """
1311       return 1
1312
1313   def GetType(self):
1314       """ 
1315           Retourne le type de valeur attendu par l'objet représenté par l'item.
1316       """
1317       return self.object.get_type()
1318
1319   def GetIntervalle(self):
1320       """ 
1321            Retourne le domaine de valeur attendu par l'objet représenté 
1322            par l'item.
1323       """
1324       return self.object.getintervalle()
1325
1326   def IsInIntervalle(self,valeur):
1327       """ 
1328           Retourne 1 si la valeur est dans l'intervalle permis par
1329           l'objet représenté par l'item.
1330       """
1331       return self.object.isinintervalle(valeur)
1332
1333   def set_valeur_co(self,nom_co):
1334       """
1335       Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
1336       """
1337       return self.object.set_valeur_co(nom_co)
1338       
1339   def get_sd_avant_du_bon_type(self):
1340       """
1341       Retourne la liste des noms des SD présentes avant l'étape qui contient
1342       le MCS pointé par self et du type requis par ce MCS
1343       """
1344       return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
1345                                                                self.object.definition.type)
1346     
1347   def GetListeValeurs(self) :
1348       """ Retourne la liste des valeurs de object """
1349       return self.object.get_liste_valeurs()
1350     
1351   def verif(self):
1352       pass
1353
1354   def isvalid(self):
1355     return self.object.isvalid()
1356
1357   def eval_valeur(self,valeur):
1358       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
1359       de l'objet pointé par self :
1360         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
1361         - retourne 'valeur' (chaîne de caractères) sinon """
1362       return self.object.eval_valeur(valeur)
1363
1364   def is_CO(self,valeur=None):
1365       """
1366          Indique si valeur est un concept produit de la macro
1367          Cette méthode n'a de sens que pour un MCSIMP d'une MACRO
1368          Si valeur vaut None on teste la valeur du mot cle
1369       """
1370       # Pour savoir si un concept est un nouveau concept de macro
1371       # on regarde s'il est présent dans l'attribut sdprods de l'étape
1372       # ou si son nom de classe est CO.
1373       # Il faut faire les 2 tests car une macro non valide peut etre
1374       # dans un etat pas tres catholique avec des CO pas encore types
1375       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
1376       if not valeur:valeur=self.object.valeur
1377       if valeur in self.object.etape.sdprods:return 1
1378       if type(valeur) is not types.ClassType:return 0
1379       if valeur.__class__.__name__ == 'CO':return 1
1380       return 0
1381
1382   def delete_valeur_co(self,valeur=None):
1383       """
1384            Supprime la valeur du mot cle (de type CO)
1385            il faut propager la destruction aux autres etapes
1386       """
1387       if not valeur : valeur=self.object.valeur
1388       # XXX faut il vraiment appeler del_sdprod ???
1389       #self.object.etape.parent.del_sdprod(valeur)
1390       self.object.etape.parent.delete_concept(valeur)
1391
1392 import Accas
1393 treeitem = SIMPTreeItem
1394 objet = Accas.MCSIMP
1395