Salome HOME
PN : pour les clefs documentaires
[tools/eficas.git] / Editeur / composimp.py
index 9168f2d9a3215f3057c7e7e84db3a4925f526a6b..b1d4bbdb412e75c1565adda05236bdcd03326c28 100644 (file)
@@ -21,8 +21,6 @@
 import string,types,os
 from Tkinter import *
 import Pmw
-from tkFileDialog import *
-from tkMessageBox import showinfo
 from copy import copy,deepcopy
 import traceback
 
@@ -37,1223 +35,336 @@ from widgets import FenetreDeSelection
 from Noyau.N_CR import justify_text
 from utils import substract_list
 
-
-class newSIMPPanel(panels.OngletPanel):
-  """
-  Classe virtuelle servant de classe mère à toutes les classes Panel
-  servant à afficher et récupérer la valeur d'un mot-clé simple.
-  Le panel est différent suivant le type de la valeur attendu
-  """
-  def init(self):
-      """
-      Méthode appelée par le constructeur de OngletPanel :
-      construit le notebook à 2 onglets utilisé par tous les panels de
-      tous les mots-clés simples
-      """
-      nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
-      nb.pack(fill = 'both', expand = 1)
-      self.nb=nb
-      nb.add('Valeur', tab_text='Saisir valeur')
-      #nb.add('Commentaire',tab_text='Insérer commentaire')
-      self.makeValeurPage(nb.page('Valeur'))
-      #self.makeCommentairePage(nb.page("Commentaire"))
-      nb.setnaturalsize()
-      
-# ----------------------------------------------------------------------------------------
-#   Méthodes utlisées pour l'affectation de la valeur donnée par l'utilisateur
-#    au mot-clé courant
-# ----------------------------------------------------------------------------------------
-
-  def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
-      """
-          Enregistre  val comme valeur de self.node.item.object SANS 
-          faire de test de validité
-      """
-      if self.parent.modified == 'n' : self.parent.init_modif()
-      if name != None:
-          valeur =name
-      else :
-          valeur= self.entry.get()
-          self.entry.delete(0,END)
-      self.node.item.set_valeur(valeur,evaluation='non')
-      self.parent.appli.affiche_infos(mess)
-      if self.node.item.get_position()=='global':
-          self.node.etape.verif_all()
-      elif self.node.item.get_position()=='global_jdc':
-          self.node.racine.verif_all()
-      else :
-          self.node.parent.verif()
-      self.node.update()
-      if self.node.item.isvalid():
-          self.node.parent.select()
-# ----------------------------------------------------------------------------------------
-#   Méthodes utlisées pour la manipulation des items dans les listes de choix
-# ----------------------------------------------------------------------------------------
-  def selectValeur(self,name):
-      self.selected_valeur = name
-
-  def deselectValeur(self,name):
-      self.selectValeur = None
-
-  def sup_valeur(self,name=None):
-      """
-      Supprime la valeur selectionnée de la liste des valeurs et la rajoute
-      à la liste des choix possibles
-      """
-      liste_valeurs = self.Liste_valeurs.get_liste()
-      liste_valeurs.remove(self.selected_valeur)
-      liste_choix = self.node.item.get_definition().into
-      liste_choix = substract_list(liste_choix,liste_valeurs)
-      self.Liste_valeurs.put_liste(liste_valeurs)
-      self.Liste_choix.put_liste(liste_choix)
-      self.selected_valeur = None
-
-  def add_choix(self,name=None):
-      """
-      Ajoute le choix selectionné à la liste des valeurs et le retire
-      de la liste des choix possibles
-      """
-      min,max = self.node.item.GetMinMax()
-      liste_valeurs = self.Liste_valeurs.get_liste()
-      if len(liste_valeurs) >= max :
-          self.parent.appli.affiche_infos("La liste ne peut pas avoir plus de %d éléments" %max)
-          return
-      liste_valeurs.append(self.selected_choix)
-      liste_choix = self.Liste_choix.get_liste()
-      liste_choix.remove(self.selected_choix)
-      self.Liste_valeurs.put_liste(liste_valeurs)
-      self.Liste_choix.put_liste(liste_choix)
-      self.selected_choix = None
-
-  def selectChoix(self,name):
-      self.selected_choix = name
-
-  def deselectChoix(self,name):
-      self.selectChoix = None
-      
-class SHELLPanel(newSIMPPanel):
-  """
-  Classe Panel utilisé pour les mots-clés simples qui attendent un shell pour valeur
-  """
-
-  def makeValeurPage(self,page):
-      """ 
-      Affiche la page concernant l'objet pointé par self qui attend un shell
-      """
-      objet_mc = self.node.item.get_definition()
-      aide = self.gen_aide()
-      aide = justify_text(texte=aide)
-      self.frame = Frame(page)
-      self.frame.place(relx=0,rely=0,relwidth=1,relheight=1)
-      label_aide = Label(self.frame,text = aide)
-      label_aide.place(relx=0.5,rely=0.1,anchor='center')
-      self.text = Text(self.frame,bg='gray95')
-      self.text.place(relx=0.2,rely=0.2,relwidth=0.6,relheight=0.6)
-      but_val = Button(self.frame,text='Valider',command = self.valide_shell)
-      but_ann = Button(self.frame,text='Annuler',command = self.annule_shell)
-      but_val.place(relx=0.35,rely=0.9,anchor='center')
-      but_ann.place(relx=0.65,rely=0.9,anchor='center')
-      self.display_valeur()
-
-  def gen_aide(self):
-      """
-      Retourne une chaîne de caractères d'aide sur la valeur qu'attend l'objet
-      pointé par self
-      """
-      return "Un shell est attendu"
-    
-  def valide_shell(self,event=None):
-      """
-      Récupère la valeur saisie par l'utilisateur dans self.text
-      et la stocke dans l'objet MCSIMP courant
-      """
-      texte = self.text.get(1.0,END)
-      self.record_valeur(texte)
-
-  def annule_shell(self,event=None):
-      """
-      Annule toute saisie dans self.text
-      """
-      self.text.delete(0,END)
-
-  def display_valeur(self,val=None):
-      """
-      Affiche la valeur de l'objet pointé par self
-      """
-      if val != None :
-          valeur = val
-      else:
-          valeur = self.node.item.get_valeur()
-      if valeur == None : return
-      self.text.insert(END,valeur)
-
-class PLUSIEURS_Panel(newSIMPPanel):
-  """
-  Classe virtuelle servant de classe mère à toutes celles définissant
-  un panneau pour un mot-clé simple qui attend une liste de valeurs
-  """
-  def accepte_modifs_valeur(self,min,max):
-      """
-      Méthode qui récupère la liste des valeurs donnée par l'utilisateur
-      et l'affecte au mot-clé courant.
-      """
-      l_valeurs = self.Liste_valeurs.get_liste()
-      longueur = len(l_valeurs)
-      if longueur < min or longueur > max :
-          self.parent.appli.affiche_infos("Valeur refusée : nombre d'éléments incorrect dans la liste")
-          return
-      if longueur > 1:
-         valeur = tuple(l_valeurs)
-      elif longueur == 1:
-         valeur = l_valeurs[0]
-      else:
-         valeur = None
-      self.parent.appli.affiche_infos("Valeur acceptée")
-      self.record_valeur(valeur)
-      if self.node.item.isvalid():
-          self.node.parent.select()
-      # fermeture de la fenêtre de sélection
-      if self.ajout_valeurs:
-          self.ajout_valeurs.quit()
-          
-  def annule_modifs_valeur(self):
-      """
-      RAZ de la liste des valeurs (annule toutes les valeurs saisies par l'utilisateur)
-      """
-      self.node.select()
-      # fermeture de la fenêtre de sélection
-      if self.ajout_valeurs:
-          self.ajout_valeurs.quit()
-          
-  def traite_reel(self,valeur):
-      """
-      Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
-      ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
-      ou un EVAL ...
-      """
-      valeur = string.strip(valeur)
-      liste_reels = self.node.item.get_sd_avant_du_bon_type()
-      if valeur in liste_reels:
-          return valeur
-      if len(valeur) >= 3 :
-          if valeur[0:4] == 'EVAL' :
-              # on a trouvé un EVAL --> on retourne directement la valeur
-              return valeur
-      if string.find(valeur,'.') == -1 :
-          # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
-          return valeur+'.'
-      else:
-          return valeur
-        
-  def add_valeur_sans_into(self,name=None):
-      """
-      Lit ce que l'utilisateur a saisi dans self.entry et cherche à
-      l'évaluer :
-      - si la valeur est acceptable, elle est ajoutée dans la liste des valeurs
-      - sinon elle est refusée
-      """
-      min,max = self.node.item.GetMinMax()
-      if name != None :
-          valeur = name
-      else:
-          valeur = self.get_valeur()
-      if self.node.item.wait_reel():
-          valeur = self.traite_reel(valeur)
-      if self.node.item.wait_geom():
-          val,test1 = valeur,1
-      else:
-          val,test1 = self.node.item.object.eval_valeur(valeur)
-      if test1 :
-          test2 = self.node.item.object.verif_type(val)
-          if test2 :
-              liste_valeurs = self.Liste_valeurs.get_liste()
-              if len(liste_valeurs) >= max :
-                  self.parent.appli.affiche_infos("La liste a déjà atteint le nombre maximum d'éléments, ajout refusé")
-                  self.erase_valeur()
-                  return
-              liste_valeurs.append(val)
-              self.Liste_valeurs.put_liste(liste_valeurs)
-              self.erase_valeur()
-              self.parent.appli.affiche_infos("Nouvelle valeur acceptée")
-          else:
-              self.parent.appli.affiche_infos("Valeur incorrecte : ajout à la liste refusé")
-      else:
-          print "impossible d'évaluer %s" %val
-          self.parent.appli.affiche_infos("Valeur incorrecte : ajout à la liste refusé")
-      #if self.node.item.isvalid():
-      #    self.node.parent.select()
-
-  def sup_valeur_sans_into(self,name=None):
-      """
-      Méthode qui sert à retirer de la liste des valeurs la valeur sélectionnée
-      """
-      liste_valeurs = self.Liste_valeurs.get_liste()
-      try:
-          liste_valeurs.remove(self.selected_valeur)
-      except:
-          # la valeur sélectionnée n'est pas dans la liste
-          return
-      self.Liste_valeurs.put_liste(liste_valeurs)
-      #self.display_valeur('')
-      self.display_valeur(self.selected_valeur)
-      self.selected_valeur = None      
-
-  def display_valeur(self,val=None):
-      """
-      Affiche la valeur passée en argument dans l'entry de saisie.
-      Par défaut affiche la valeur du mot-clé simple
-      """
-      if not val :
-          valeur = self.node.item.getval()
-      else:
-          valeur = val
-      self.entry.delete(0,END)
-      if not valeur : return
-      self.entry.insert(0,str(valeur))
-      
-            
-class PLUSIEURS_INTO_Panel(PLUSIEURS_Panel):
-  """
-  Classe servant à définir le panneau permettant d'afficher et de saisir une
-  liste de valeurs à choisir parmi une liste discrètes de valeurs possibles
-  """
-  def makeValeurPage(self,page):
-      """
-      Génère la page de saisie de plusieurs valeurs parmi un ensemble discret
-      de possibles
-      """
-      self.ajout_valeurs = None
-      # On récupère la bulle d'aide du panneau, l'objet, min et max (cardinalité de la liste),
-      # la liste des choix et la liste des valeurs
-      bulle_aide=self.get_bulle_aide()
-      objet_mc = self.node.item.get_definition()
-      min,max = self.node.item.GetMinMax()
-      l_choix=list(objet_mc.into)
-      l_choix.sort()
-      l_valeurs = self.node.item.GetListeValeurs()
-      # remplissage du panneau
-      self.frame_valeurs = Frame(page)
-      self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
-      self.frame_boutons_fleches = Frame(page)
-      self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
-      self.frame_choix = Frame(page)
-      self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
-      self.frame_boutons = Frame(page)
-      self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
-      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
-                                 ("<Button-3>",self.deselectValeur),
-                                 ("<Double-Button-1>",self.sup_valeur))
-      liste_commandes_choix = (("<Button-1>",self.selectChoix),
-                               ("<Button-3>",self.deselectChoix),
-                               ("<Double-Button-1>",self.add_choix))
-      self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
-                                      titre="Valeur(s) actuelle(s)")
-      self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
-                                    titre= "Valeurs possibles")
-      bouton_add = Button(self.frame_boutons_fleches,
-                          #text="<--",
-                          image = images.get_image('arrow_left'),
-                          command = self.add_choix)
-      bouton_sup = Button(self.frame_boutons_fleches,
-                          #text="-->",
-                          image = images.get_image('arrow_right'),
-                          command = self.sup_valeur)
-      bouton_accepter = Button(self.frame_boutons,
-                               text='Valider',
-                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
-      bouton_annuler = Button(self.frame_boutons,
-                              text = 'Annuler',
-                              command = self.annule_modifs_valeur)
-      bouton_add.place(relx=0.3,rely=0.35)
-      bouton_sup.place(relx=0.3,rely=0.65)
-      for but in (bouton_accepter,bouton_annuler):
-          but.pack(side='left',padx=5)
-      self.Liste_valeurs.affiche_liste()
-      self.Liste_choix.affiche_liste()
-      for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
-          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-
-  def get_bulle_aide(self):
-      """
-      Retourne la bulle d'aide du panneau (affichée par clic droit)
-      """
-      return """Un clic sur une valeur des deux listes la sélectionne.
-      - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
-      dans la liste des valeurs que vous voulez affecter au mot-clé simple
-      - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
-      sélectionnée (elle apparaît alors à nouveau comme choix possible
-      dans la liste des choix à droite)
-      - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
-      au mot-clé simple courant
-      - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
-      avant toute modification depuis le dernier 'Valider'"""
-
-class PLUSIEURS_BASE_Panel(PLUSIEURS_Panel):
-  """
-  Classe définissant le panel associé aux mots-clés qui demandent
-  à l'utilisateur de donner une liste de valeurs qui ne sont pas
-  à choisir dans une liste discrètes et qui sont de type de base :
-  entier, réel, string,...
-  """
-  def makeValeurPage(self,page):
-      """
-      Crée la page de saisie d'une liste de valeurs à priori quelconques,
-      cad qui ne sont  pas à choisir dans une liste prédéfinie
-      """
-      # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
-      # et la liste des valeurs déjà affectées à l'objet courant
-      bulle_aide=self.get_bulle_aide()
-      objet_mc = self.node.item.get_definition()
-      aide = self.get_aide()
-      aide = justify_text(texte=aide)
-      min,max = self.node.item.GetMinMax()
-      l_valeurs = self.node.item.GetListeValeurs()
-      # création des frames globales
-      self.frame1 = Frame(page,relief='groove',bd=2)
-      self.frame2 = Frame(page)
-      self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.85)
-      self.frame2.place(relx=0.,rely=0.85,relwidth=1,relheight=0.15)
-      self.frame_right = Frame(self.frame1)
-      self.frame_right.place(relx=0.35,rely=0.,relwidth=0.65,relheight=1.)
-      # création des frames internes
-      self.frame_valeurs = Frame(self.frame1)
-      self.frame_valeurs.place(relx=0.02,rely=0.05,relwidth=0.35,relheight=0.95)
-      self.frame_boutons_fleches = Frame(self.frame_right)
-      self.frame_boutons_fleches.place(relx=0.,rely=0.2,relwidth=0.2,relheight=0.5)
-      self.frame_choix = Frame(self.frame_right)
-      self.frame_choix.place(relx=0.2,rely=0.2,relwidth=0.7,relheight=0.5)
-      self.frame_aide = Frame(self.frame_right)
-      self.frame_aide.place(relx=0.1,rely=0.7,relwidth=0.8,relheight=0.3)
-      self.frame_boutons = Frame(self.frame2)
-      self.frame_boutons.place(relx=0.35,rely=0.,relwidth=0.3,relheight=1.)
-      for fram in (self.frame1,self.frame2,self.frame_right,self.frame_valeurs,
-                 self.frame_boutons_fleches,self.frame_choix,self.frame_aide,self.frame_boutons):
-          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-      # création des objets dans les frames
-      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
-                                 ("<Button-3>",self.deselectValeur),
-                                 ("<Double-Button-1>",self.sup_valeur_sans_into))
-      self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
-                                      titre="Valeur(s) actuelle(s)")
-      # Création de l'entry ou de la liste des SD
-      self.label = Label(self.frame_choix,text="Valeur :")
-      self.make_entry(frame = self.frame_choix,command = self.add_valeur_sans_into)
-      self.label.place(relx=0.05,rely=0.5)
-      # Création d'un bouton "Importer ..." sur le panel.
-      bouton_valeurs_fichier = Button(self.frame_choix,
-                                      text="Importer ...",
-                                      command=self.select_in_file)
-      bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)
-      self.ajout_valeurs = None
-      # boutons Ajouter et Supprimer
-      bouton_add = Button(self.frame_boutons_fleches,
-                          image = images.get_image('arrow_left'),
-                          command = self.add_valeur_sans_into)
-      bouton_sup = Button(self.frame_boutons_fleches,
-                          image = images.get_image('arrow_right'),
-                          command = self.sup_valeur_sans_into)
-      bouton_add.place(relx=0.3,rely=0.35)
-      bouton_sup.place(relx=0.3,rely=0.65)
-      # affichage de l'aide
-      self.frame_aide.update()
-      self.aide = Label(self.frame_aide,
-                        text = aide,
-                        justify='center',
-                        anchor='center',
-                       wraplength=int(self.frame_aide.winfo_width()*0.8))
-      self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
-      self.Liste_valeurs.affiche_liste()
-      # boutons Accepter et Annuler
-      bouton_accepter = Button(self.frame_boutons,
-                               text='Valider',
-                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
-      bouton_annuler = Button(self.frame_boutons,
-                              text = 'Annuler',
-                              command = self.annule_modifs_valeur)
-      for but in (bouton_accepter,bouton_annuler):
-          but.pack(side='left',padx=5)
-
-  def select_in_file(self):
-      """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
-      nom_fichier = askopenfilename(title="Choix fichier :")
-      if nom_fichier == "":
-          return
-      try:
-          f = open(nom_fichier, "rb")
-          selection_texte = f.read()
-          f.close()
-          self.ajout_valeurs = FenetreDeSelection(self, 
-                                                 self.node.item,
-                                                 self.parent.appli,
-                                                 titre="Sélection de valeurs",
-                                                 texte=selection_texte)
-      except:
-          traceback.print_exc()
-          showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
-          
-  def get_bulle_aide(self):
-      """
-      Retourne l'aide associée au panneau courant
-      """
-      return """Taper dans la boîte de saisie de droite la valeur que
-      vous voulez affecter au mot-clé simple.
-      - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
-      dans la liste des valeurs que vous voulez affecter au mot-clé simple
-      - Un clic sur une valeur de la liste la sélectionne
-      - Un clic sur la flèche droite ou un double-clic retire la valeur
-      sélectionnée de la liste
-      - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
-      au mot-clé simple
-      - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
-      depuis le dernier clic sur 'Valider'"""
-
-  def get_aide(self):
-      """
-      Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
-      que saisit l'utilisateur
-      """
-      mc = self.node.item.get_definition()
-      d_aides = { 'TXM' : 'chaînes de caractères',
-                  'R'   : 'réels',
-                  'I'   : 'entiers',
-                  'C'   : 'complexes'}
-      type = mc.type[0]
-      if not d_aides.has_key(type) : return 'Type de base inconnu'
-      if mc.min == mc.max:
-          return "Une liste de "+d_aides[type]+" chaînes de caractères est attendue"
-      else :
-          return "Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
-
-  def make_entry(self,frame,command):
-      """
-      Crée l'entry de saisie de la valeur souhaitée : distingue le
-      cas d'un complexe attendu, d'une autre valeur quelconque
-      """
-      if self.node.item.wait_complex():
-          self.typ_cplx=StringVar()
-          self.typ_cplx.set('RI')
-          rb1 = Radiobutton(frame, text='RI',variable=self.typ_cplx,value='RI')
-          rb2 = Radiobutton(frame, text='MP',variable=self.typ_cplx,value='MP')
-          self.entry1 = Pmw.EntryField(frame,validate='real')
-          self.entry2 = Pmw.EntryField(frame,validate='real')
-          rb1.place(relx=0.05,rely = 0.4)
-          rb2.place(relx=0.05,rely = 0.6)
-          self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus)
-          self.entry2.component('entry').bind("<Return>",lambda e,c=command:c())
-          self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
-          self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
-          self.entry1.focus()
-      else:
-          self.entry = Entry(frame,relief='sunken')
-          self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
-          self.entry.bind("<Return>",lambda e,c=command:c())
-          self.entry.focus()
-
-  def get_valeur(self):
-      """
-      Retourne la valeur saisie par l'utilisateur dans self.entry
-      """
-      return self.entry.get()
-
-  def erase_valeur(self):
-      """
-      Efface la valeur donnée par l'utilisateur dans l'entry
-      """
-      self.entry.delete(0,END)
-        
-class PLUSIEURS_ASSD_Panel(PLUSIEURS_Panel):
-  """
-  Classe définissant le panel associé aux mots-clés qui demandent
-  à l'utilisateur de donner une liste de valeurs qui ne sont pas
-  à choisir dans une liste discrètes et qui sont de type dérivé d'ASSD
-  """
-  def makeValeurPage(self,page):
-      """
-      Génère la page de saisie de plusieurs noms de SD parmi un ensemble discret
-      de SD possibles, cad d'un type cohérent avec les types attendus par le mot-clé simple
-      """
-      # On récupère la bulle d'aide du panneau, l'objet, l'aide, min et max (cardinalité de la liste),
-      # la liste des valeurs déjà affectées à l'objet courant et la liste des SD du bon type
-      bulle_aide=self.get_bulle_aide()
-      self.ajout_valeurs=None
-      objet_mc = self.node.item.get_definition()
-      aide = self.get_aide()
-      aide = justify_text(texte=aide)
-      min,max = self.node.item.GetMinMax()
-      l_valeurs = self.node.item.GetListeValeurs()
-      l_choix=self.node.item.get_sd_avant_du_bon_type()
-      l_choix.sort()
-      # remplissage du panneau
-      self.frame_valeurs = Frame(page)
-      self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
-      self.frame_boutons_fleches = Frame(page)
-      self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
-      self.frame_choix = Frame(page)
-      self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
-      self.frame_boutons = Frame(page)
-      self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.3,relheight=0.1)
-      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
-                                 ("<Button-3>",self.deselectValeur),
-                                 ("<Double-Button-1>",self.sup_valeur_sans_into))
-      liste_commandes_choix = (("<Button-1>",self.selectChoix),
-                               ("<Button-3>",self.deselectChoix),
-                               ("<Double-Button-1>",self.add_valeur_sans_into))
-      self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
-                                      titre="Valeur(s) actuelle(s)")
-      self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
-                                    titre= "Valeurs possibles")
-      bouton_add = Button(self.frame_boutons_fleches,
-                          #text="<--",
-                          image = images.get_image('arrow_left'),
-                          command = self.add_valeur_sans_into)
-      bouton_sup = Button(self.frame_boutons_fleches,
-                          #text="-->",
-                          image = images.get_image('arrow_right'),
-                          command = self.sup_valeur_sans_into)
-      bouton_accepter = Button(self.frame_boutons,
-                               text='Valider',
-                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
-      bouton_annuler = Button(self.frame_boutons,
-                              text = 'Annuler',
-                              command = self.annule_modifs_valeur)
-      bouton_add.place(relx=0.3,rely=0.35)
-      bouton_sup.place(relx=0.3,rely=0.65)
-      for but in (bouton_accepter,bouton_annuler):
-          but.pack(side='left',padx=5)
-      self.Liste_valeurs.affiche_liste()
-      self.Liste_choix.affiche_liste()
-      for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
-          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-
-  def get_bulle_aide(self):
-      """
-      Retourne la bulle d'aide associée au panneau
-      """
-      return """Un clic sur une valeur des deux listes la sélectionne.
-      - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
-      dans la liste des valeurs que vous voulez affecter au mot-clé simple
-      - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
-      sélectionnée (elle apparaît alors à nouveau comme choix possible
-      dans la liste des choix à droite)
-      - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
-      au mot-clé simple courant
-      - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
-      avant toute modification depuis le dernier 'Valider'"""
-
-  def get_aide(self):
-      """
-      Retourne la phrase d'aide indiquant de quel type doivent être les
-      valeurs que doit entrer l'utilisateur
-      """
-      mc = self.node.item.get_definition()
-      type = mc.type[0].__name__  
-      if len(mc.type)>1 :
-          for typ in mc.type[1:] :
-              type = type + ' ou '+typ.__name__
-      if mc.min == mc.max:
-        return "Une liste de "+`mc.min`+" objets de type "+type+" est attendue"
-      else :
-        return "Une liste d'objets de type "+type+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
-    
-  def sup_valeur(self,name=None):
-      """
-      Supprime la valeur selectionnée de la liste des valeurs et la rajoute
-      à la liste des choix possibles
-      """
-      liste_valeurs = self.Liste_valeurs.get_liste()
-      liste_valeurs.remove(self.selected_valeur)
-      liste_choix = self.node.item.get_definition().into
-      liste_choix = substract_list(liste_choix,liste_valeurs)
-      self.Liste_valeurs.put_liste(liste_valeurs)
-      self.Liste_choix.put_liste(liste_choix)
-      self.selected_valeur = None      
-    
-  def erase_valeur(self):
-      pass
-
-  def get_valeur(self):
-      """
-      Retourne la valeur sélectionnée dans la liste des choix
-      """
-      return self.selected_choix
-
-  def display_valeur(self,val=None):
-      """
-         Affiche la valeur passée en argument dans l'entry de saisie.
-         Par défaut affiche la valeur du mot-clé simple
-      """
-      # Il n'y a pas d'entry pour ce type de panneau
-      return
-
-    
-class UNIQUE_Panel(newSIMPPanel):
-  """
-  Classe virtuelle servant de classe mère à toutes celles définissant un panneau
-  permettant l'affichage et la saisie d'une valeur unique pour le mot-clé simple
-  """
-
-  def erase_valeur(self):
-      """
-      Efface l'entry de saisie
-      """
-      self.entry.delete(0,END)
-
-  def get_valeur(self):
-      """
-      Retourne la valeur donnée par l'utilisateur
-      """
-      return self.entry.get()
-    
-  def valid_valeur(self):
-      """
-      Teste si la valeur fournie par l'utilisateur est une valeur permise :
-      - si oui, l'enregistre
-      - si non, restaure l'ancienne valeur
-      """
-      if self.parent.modified == 'n' : self.parent.init_modif()
-      valeur = self.get_valeur()
-      self.erase_valeur()
-      anc_val = self.node.item.get_valeur()
-      test = self.node.item.set_valeur(valeur)
-      if not test :
-          mess = "impossible d'évaluer : %s " %`valeur`
-          self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
-      elif self.node.item.isvalid() :
-          self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
-         if self.node.item.get_position()=='global':
-              self.node.etape.verif_all()
-         elif self.node.item.get_position()=='global_jdc':
-              self.node.racine.verif_all()
-         else :
-              self.node.parent.verif()
-         self.node.update()
-          self.node.parent.select()
-      else :
-          cr = self.node.item.get_cr()
-          mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
-          self.record_valeur(anc_val,mess=mess)
-
-class UNIQUE_INTO_Panel(UNIQUE_Panel):
-  """
-  Classe définissant le panel associé aux mots-clés qui demandent
-  à l'utilisateur de choisir une seule valeur parmi une liste de valeurs
-  discrètes
-  """
-  def makeValeurPage(self,page):
-      """
-      Génère la page de saisie d'une seule valeur parmi un ensemble
-      discret de possibles
-      """
-      # récupération de la bulle d'aide et de l'objet mc
-      bulle_aide=self.get_bulle_aide()
-      objet_mc = self.node.item.get_definition()
-      # remplissage du panel
-      self.frame_valeur = Frame(page)
-      self.frame_valeur.pack(fill='both',expand=1)
-      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-      l_choix=list(objet_mc.into)
-      l_choix.sort()
-      self.label = Label(self.frame_valeur,text='Choisir une valeur :')
-      self.label.pack(side='top')
-      self.frame = Frame(page)
-      self.frame.place(relx=0.33,rely=0.2,relwidth=0.33,relheight=0.6)
-      liste_commandes = (("<Button-1>",self.selectChoix),
-                         ("<Button-3>",self.deselectChoix),
-                         ("<Double-Button-1>",self.record_valeur))
-      self.Liste_choix = ListeChoix(self,self.frame,l_choix,liste_commandes = liste_commandes,
-                                    titre="Valeurs possibles")
-      self.Liste_choix.affiche_liste()
-
-  def get_bulle_aide(self):
-      """
-      Retourne la bulle d'aide affectée au panneau courant (affichée par clic droit)
-      """
-      return """Double-cliquez sur la valeur désirée
-      pour valoriser le mot-clé simple courant"""
-
-class UNIQUE_ASSD_Panel(UNIQUE_Panel):
-  """
-  Classe servant à définir le panneau associé aux objets qui attendent une valeur unique
-  d'un type dérivé d'ASSD
-  """
-  def makeValeurPage(self,page):
-      """
-          Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une 
-          SD de type dérivé d'ASSD
-      """
-      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
-      # et de la liste des SD du bon type (constituant la liste des choix)
-      bulle_aide=self.get_bulle_aide()
-      aide=self.get_aide()
-      aide= justify_text(texte=aide)
-      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
-      # Remplissage du panneau
-      self.valeur_choisie = StringVar()
-      self.valeur_choisie.set('')
-      self.frame_valeur = Frame(page)
-      self.frame_valeur.pack(fill='both',expand=1)
-      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-      self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
-                                         items=liste_noms_sd,
-                                         labelpos='n',
-                                         label_text="Structures de données du type\n requis par l'objet courant :",
-                                         listbox_height = 6,
-                                         selectioncommand=self.select_valeur_from_list,
-                                         dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
-      self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
-      Label(self.frame_valeur,text='Structure de donnée choisie :').place(relx=0.05,rely=0.6)
-      #self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
-      Label(self.frame_valeur,textvariable=self.valeur_choisie).place(relx=0.5,rely=0.6)
-      # affichage de la valeur courante
-      self.display_valeur()
-
-  def get_bulle_aide(self):
-      """
-      Retourne l'aide associée au panneau
-      """
-      return "Double-cliquez sur la structure de donnée désirée pour valoriser le mot-clé simple courant"
-
-  def get_aide(self):
-      """
-      Retourne la phrase d'aide indiquant de quel type doit être la valeur à donner par l'utilisateur
-      """
-      mc = self.node.item.get_definition()
-      type = mc.type[0].__name__  
-      if len(mc.type)>1 :
-          for typ in mc.type[1:] :
-              type = type + ' ou '+typ.__name__
-      return  "Un objet de type "+type+" est attendu"
-    
-  def select_valeur_from_list(self):
-      """
-      Affecte à valeur choisie la sélection courante dans la liste des choix proposée
-      """
-      if len(self.listbox.get()) == 0 : return
-      choix = self.listbox.getcurselection()[0]
-      self.valeur_choisie.set(choix)
-
-  def choose_valeur_from_list(self,command):
-      """
-      Affecte à valeur choisie la sélection courante dans la liste des choix proposée
-      Exécute command
-      """
-      if len(self.listbox.get()) == 0 : return
-      choix = self.listbox.getcurselection()[0]
-      self.valeur_choisie.set(choix)
-      apply(command,(),{})
-
-  def get_valeur(self):
-      """
-      Retourne la valeur donnée par l'utilisateur au MCS
-      """
-      return self.valeur_choisie.get()
-    
-  def display_valeur(self):
-      """
-      Affiche la valeur de l'objet pointé par self
-      """
-      valeur = self.node.item.get_valeur()
-      if valeur == None : return # pas de valeur à afficher ...
-      self.valeur_choisie.set(valeur.nom)
-
-  def erase_valeur(self):
-      pass
-
-class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel):
-  """
-  Classe servant à définir le panneau correspondant à un mot-clé simple
-  qui attend une valeur unique de type dérivé d'ASSD ou non encore
-  existante (type CO(...) utilisé dans les macros uniquement)
-  """
-  def makeValeurPage(self,page):
-      """
-      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une SD de type dérivé
-      d'ASSD
-      """
-      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
-      # et de la liste des SD du bon type (constituant la liste des choix)
-      bulle_aide=self.get_bulle_aide()
-      aide=self.get_aide()
-      aide= justify_text(texte=aide)
-      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
-      # Remplissage du panneau
-      self.frame_valeur = Frame(page)
-      self.frame_valeur.pack(fill='both',expand=1)
-      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-      # affichage de la liste des SD existantes et du bon type
-      self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
-                                         items=liste_noms_sd,
-                                         labelpos='n',
-                                         label_text="Structures de données du type\n requis par l'objet courant :",
-                                         listbox_height = 6,
-                                         selectioncommand=self.select_valeur_from_list,
-                                         dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
-      self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
-      # affichage du bouton 'Nouveau concept'
-      self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ",
-                                 items = ('NON','OUI'),menubutton_width=10)
-      self.b_co.configure(command = lambda e,s=self : s.ask_new_concept())
-      self.b_co.place(relx=0.05,rely=0.6,anchor='w')
-      self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :')
-      self.entry_co = Entry(self.frame_valeur)
-      self.entry_co.bind('<Return>',self.valid_nom_concept_co)
-      # affichage du label de la structure de donnée choisie
-      self.l_resu = Label(self.frame_valeur,text='Structure de donnée choisie :')
-      self.valeur_choisie = StringVar()
-      self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
-      self.frame_valeur.update()
-      self.aide = Label(self.frame_valeur,
-                        text = aide,
-                       wraplength=int(self.frame_valeur.winfo_width()*0.8),
-                       justify='center')
-      self.aide.place(relx=0.5,rely=0.85,anchor='n')
-      # affichage de la valeur courante
-      self.display_valeur()
-      
-  def get_bulle_aide(self):
-      """
-      Retourne la bulle d'aide du panneau
-      """
-      return """Double-cliquez sur la structure de donnée désirée
-      pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour
-      entrer le nom d'un concept non encore existant"""
-
-  def valid_valeur(self):
-      """
-      Teste si la valeur fournie par l'utilisateur est une valeur permise :
-      - si oui, l'enregistre
-      - si non, restaure l'ancienne valeur
-      """
-      if self.parent.modified == 'n' : self.parent.init_modif()
-      valeur = self.get_valeur()
-      self.erase_valeur()
-      anc_val = self.node.item.get_valeur()
-      test_CO=self.node.item.is_CO(anc_val)
-      test = self.node.item.set_valeur(valeur)
-      if not test :
-          mess = "impossible d'évaluer : %s " %`valeur`
-          self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess)
-          return
-      elif self.node.item.isvalid() :
-          self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
-          if test_CO:
-             # il faut egalement propager la destruction de l'ancien concept
-             self.node.item.delete_valeur_co(valeur=anc_val)
-             # et on force le recalcul des concepts de sortie de l'etape
-             self.node.item.object.etape.get_type_produit(force=1)
-             # et le recalcul du contexte
-             self.node.item.object.etape.parent.reset_context()
-          self.node.parent.select()
-      else :
-          cr = self.node.item.get_cr()
-          mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
-          self.record_valeur(anc_val,mess=mess)
-          return
-      if self.node.item.get_position()=='global':
-          self.node.etape.verif_all()
-      elif self.node.item.get_position()=='global_jdc':
-          self.node.racine.verif_all()
-      else :
-          self.node.parent.verif()
-      self.node.update()
-
-  def valid_nom_concept_co(self,event=None):
-      """
-      Lit le nom donné par l'utilisateur au concept de type CO qui doit être
-      la valeur du MCS courant et stocke cette valeur
-      """
-      if self.parent.modified == 'n' : self.parent.init_modif()
-      anc_val = self.node.item.get_valeur()
-      nom_concept = self.entry_co.get()
-      test,mess=self.node.item.set_valeur_co(nom_concept)
-      if not test:
-          # On n'a pas pu créer le concept
-          self.parent.appli.affiche_infos(mess)
-          return
-      elif self.node.item.isvalid() :
-          self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
-          self.node.parent.select()
-      else :
-          cr = self.node.item.get_cr()
-          mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
-          self.record_valeur(anc_val,mess=mess)
-          return
-      if self.node.item.get_position()=='global':
-          self.node.etape.verif_all()
-      elif self.node.item.get_position()=='global_jdc':
-          self.node.racine.verif_all()
-      else :
-          self.node.parent.verif()
-      if self.node.item.isvalid():
-          self.node.parent.select()
-      self.node.update()
-
-  def ask_new_concept(self):
-      """
-      Crée une entry dans le panneau d'un MCS qui attend un concept OU un CO() afin de
-      permettre à l'utilisateur de donner le nom du nouveau concept
-      """
-      new_concept = self.b_co.getcurselection()
-      if new_concept == 'OUI':
-          self.label_co.place(relx=0.05,rely=0.7)
-          self.entry_co.place(relx=0.45,rely=0.7,relwidth=0.25)
-          self.l_resu.place_forget()
-          self.label_valeur.place_forget()
-          self.entry_co.focus()
-      elif new_concept == 'NON':
-          # On est passe de OUI à NON, on supprime la valeur
-          self.node.item.delete_valeur_co()
-          self.record_valeur(name=None,mess="Suppression CO enregistrée")
-          self.label_co.place_forget()
-          self.entry_co.place_forget()
-          self.l_resu.place(relx=0.05,rely=0.7)
-          self.label_valeur.place(relx=0.45,rely=0.7)
-          
-  def display_valeur(self):
-      """
-      Affiche la valeur de l'objet pointé par self
-      """
-      valeur = self.node.item.get_valeur()
-      if valeur == None or valeur == '': 
-         self.valeur_choisie.set('')
-         return # pas de valeur à afficher ...
-      # il faut configurer le bouton si la valeur est un objet CO
-      # sinon afficher le nom du concept dans self.valeur_choisie
-      if self.node.item.is_CO():
-          self.b_co.invoke('OUI')
-          self.entry_co.insert(0,valeur.nom)
-      else:
-          self.valeur_choisie.set(valeur.nom)
-
-  def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
-      """
-      Enregistre  val comme valeur de self.node.item.object SANS faire de test de validité
-      """
-      if self.parent.modified == 'n' : self.parent.init_modif()
-      if name != None:
-          valeur =name
-      else :
-          self.entry_co.delete(0,END)
-          valeur= self.entry_co.get()
-      self.node.item.set_valeur_co(valeur)
-      self.parent.appli.affiche_infos(mess)
-      # On met a jour le display dans le panneau
-      self.display_valeur()
-      if self.node.item.get_position()=='global':
-          self.node.etape.verif_all()
-      elif self.node.item.get_position()=='global_jdc':
-          self.node.racine.verif_all()
-      else :
-          self.node.parent.verif()
-      if self.node.item.isvalid():
-          self.node.parent.select()
-      self.node.update()
-
-
-class UNIQUE_BASE_Panel(UNIQUE_Panel):
-  """
-  Classe servant à définir le panneau associé aux mots-clés simples qui attendent
-  une valeur d'un type de base (entier, réel ou string).
-  """
-  def makeValeurPage(self,page):
-      """
-      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
-      de base cad entier, réel, string ou complexe
-      """
-      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
-      # et de la liste des SD du bon type (constituant la liste des choix)
-      bulle_aide=self.get_bulle_aide()
-      aide=self.get_aide()
-      aide= justify_text(texte=aide)
-      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
-      # Remplissage du panneau
-      self.frame_valeur = Frame(page)
-      self.frame_valeur.pack(fill='both',expand=1)
-      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-      self.label = Label(self.frame_valeur,text='Valeur :')
-      self.label.place(relx=0.1,rely=0.5)
-      self.entry = Entry(self.frame_valeur,relief='sunken')
-      self.entry.place(relx=0.28,rely=0.5,relwidth=0.6)
-      self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
-      self.entry.focus()
-      # aide associée au panneau
-      self.frame_valeur.update()
-      self.aide = Label(self.frame_valeur, 
-                        text = aide,
-                       wraplength=int(self.frame_valeur.winfo_width()*0.8),
-                       justify='center')
-      self.aide.place(relx=0.5,rely=0.7,anchor='n')
-      # affichage de la valeur du MCS
-      self.display_valeur()
-
-  def get_aide(self):
-      """
-      Retourne la phrase d'aide indiquant de quel type doit être la valeur
-      du mot-clé simple fournie par l'utilisateur
-      """
-      mc = self.node.item.get_definition()
-      d_aides = { 'TXM' : "Une chaîne de caractères est attendue",
-                  'R'   : "Un réel est attendu",
-                  'I'   : "Un entier est attendu"}
-      type = mc.type[0]
-      return d_aides.get(type,"Type de base inconnu")
-
-  def get_bulle_aide(self):
-      """
-      Retourne la bulle d'aide associée au panneau et affichée par clic droit
-      """
-      return """Saisissez la valeur que vous voulez affecter au mot-clé simple
-      dans la zone de saisie et pressez <Return>"""
-      
-  def display_valeur(self):
-      """
-      Affiche la valeur de l'objet pointé par self
-      """
-      valeur = self.node.item.get_valeur()
-      if valeur == None : return # pas de valeur à afficher ...
-      self.entry.delete(0,END)
-      self.entry.insert(0,valeur)
-      
-class UNIQUE_COMP_Panel(UNIQUE_Panel):
-  """
-  Classe servant à définir le panneau associé aux mots-clés simples
-  qui attendent une valeur de type complexe
-  """
-  def makeValeurPage(self,page):
-      """
-      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
-      de base cad entier, réel, string ou complexe
-      """
-      # Récupération de l'aide associée au panneau et de l'aide destinée à l'utilisateur
-      bulle_aide=self.get_bulle_aide()
-      aide=self.get_aide()
-      aide= justify_text(texte=aide)
-      # Remplissage du panneau
-      self.frame_valeur = Frame(page)
-      self.frame_valeur.pack(fill='both',expand=1)
-      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
-      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
-      self.label = Label(self.frame_valeur,text='Valeur :')
-      self.label.place(relx=0.1,rely=0.5)
-      self.typ_cplx=StringVar()
-      self.typ_cplx.set('RI')
-      rb1 = Radiobutton(self.frame_valeur, text='RI',variable=self.typ_cplx,value='RI')
-      rb2 = Radiobutton(self.frame_valeur, text='MP',variable=self.typ_cplx,value='MP')
-      self.entry1 = Pmw.EntryField(self.frame_valeur,validate='real')
-      self.entry2 = Pmw.EntryField(self.frame_valeur,validate='real')
-      rb1.place(relx=0.05,rely = 0.4)
-      rb2.place(relx=0.05,rely = 0.6)
-      self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus())
-      self.entry2.component('entry').bind("<Return>",lambda e,c=self.valid_valeur:c())
-      self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
-      self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
-      self.entry1.focus()
-      self.frame_valeur.update()
-      self.aide = Label(self.frame_valeur,
-                        text = aide,
-                        wraplength=int(self.frame_valeur.winfo_width()*0.8),
-                       justify='center')
-      self.aide.place(relx=0.5,rely=0.7,anchor='n')
-
-  def get_bulle_aide(self):
-      """
-      Retourne la bulle d'aide du panneau
-      """
-      return """-Choisissez votre format de saisie du complexe :
-      \t 'RI' = parties réelle et imaginaire
-      \t 'MP' = module/phase (en degrés)
-      - Saisissez ensuite dans les deux zones de saisie les deux nombres attendus"""
-
-  def get_aide(self):
-      """
-      Retourne la phrase d'aide décrivant le type de la valeur que peut prendre
-      le mot-clé simple courant
-      """
-      return 'Un complexe est attendu'
-
-  def get_valeur(self):
-      """
-      Retourne le complexe saisi par l'utilisateur
-      """
-      l=[]
-      l.append(self.typ_cplx.get())
-      l.append(string.atof(self.entry1.get()))
-      l.append(string.atof(self.entry2.get()))
-      return `tuple(l)`
-
-  def erase_valeur(self):
-      """
-      Efface les entries de saisie
-      """
-      self.typ_cplx = 'RI'
-      self.entry1.delete(0,END)
-      self.entry2.delete(0,END)
       
 class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
+  from newsimppanel import newSIMPPanel
   panel = newSIMPPanel
 
   def init(self) :
       self.expandable = 0
       self.affect_panel()
 
+
   def affect_panel(self):
       """
       Cette méthode attribue le panel à l'objet pointé par self en fonction de la
       nature de la valeur demandée pour cet objet
       """
+      from uniquepanel import UNIQUE_Panel
+      from plusieurspanel import PLUSIEURS_Panel
+
+      #print "affect_panel : ",self.nom,self.is_list(),self.has_into(), self.get_into(None)
+
       if self.wait_shell():
           # l'objet attend un shell
+          from shellpanel import SHELLPanel
           self.panel = SHELLPanel
-      elif self.wait_into():
+      elif self.has_into():
           # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
-          min,max = self.GetMinMax()
-          if max != 1 and ((min != 0 and min != max) or (min == 0)):
-             # l'objet attend une liste de valeurs
+          if self.is_list() :
+             from plusieursintopanel import PLUSIEURS_INTO_Panel
              self.panel = PLUSIEURS_INTO_Panel
           else:
-             # l'objet n'attend qu'une seule valeur
+             from uniqueintopanel import UNIQUE_INTO_Panel
              self.panel = UNIQUE_INTO_Panel
       else:
           # l'objet prend une ou des valeurs à priori quelconques
-          min,max = self.GetMinMax()
-          if max != 1 :
+          if self.is_list() :
               # on attend une liste de valeurs mais de quel type ?
               if self.wait_assd():
                   # on attend une liste de SD
+                  from plusieursassdpanel import PLUSIEURS_ASSD_Panel
                   self.panel = PLUSIEURS_ASSD_Panel
               else:
                   # on attend une liste de valeurs de types debase (entiers, réels,...)
+                  from plusieursbasepanel import PLUSIEURS_BASE_Panel
                   self.panel = PLUSIEURS_BASE_Panel
           else:
               # on n'attend qu'une seule valeur mais de quel type ?
               if self.wait_co():
                   # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
+                  from uniquesdcopanel import UNIQUE_SDCO_Panel
                   self.panel = UNIQUE_SDCO_Panel
               elif self.wait_assd():
                   # on attend une SD
+                  from uniqueassdpanel import UNIQUE_ASSD_Panel
                   self.panel = UNIQUE_ASSD_Panel
               else:
                   # on attend une valeur d'un type de base (entier,réel,...)
                   if self.wait_complex():
                       # on attend un complexe
+                      from uniquecomppanel import UNIQUE_COMP_Panel
                       self.panel = UNIQUE_COMP_Panel
                   else:
                       # on attend un entier, un réel ou une string
+                     from uniquebasepanel import UNIQUE_BASE_Panel
                       self.panel = UNIQUE_BASE_Panel
+      # cas particulier des fonctions
+      genea = self.get_genealogie()
+      if "VALE" in genea or "VALE_C" in genea:
+         if "DEFI_FONCTION" in genea :
+            from fonctionpanel import FONCTION_Panel
+            self.panel=FONCTION_Panel
+      #---------------------------------------------------------
+      # PN ajout pour lancement de Salome
+      #---------------------------------------------------------
+      if  self.appli.salome != 0 :
+          import panelsSalome
+
+          self.clef_fonction="SALOME"
+          for i in range(0,len( genea )) :
+             self.clef_fonction=self.clef_fonction+"_"+ genea[i]
+
+          self.select_noeud_maille=0
+          if (self.clef_fonction.find("GROUP_NO") != -1)  :
+             self.select_noeud_maille=1
+          if (self.clef_fonction.find("GROUP_MA") != -1) :
+             self.select_noeud_maille=1
+
+          recherche=panelsSalome.dict_classes_salome[self.panel]
+          if hasattr(recherche,self.clef_fonction):
+             self.panel=recherche
+          if self.select_noeud_maille==1 :
+             self.panel=recherche
+
+
+  #-----------------------------------------------
+  #
+  # Methodes liees aux informations sur le Panel
+  # ou au mot-clef simple
+  #
+  #-----------------------------------------------
+  # is_list
+  # get_into           a priori inutile --> commentee
+  # has_into
+  # wait_into          a priori inutile --> commentee
+  # GetMinMax
+  # GetMultiplicite
+  # GetIntervalle
+  # GetListeValeurs
+  # get_liste_possible
+
+  def is_list(self):
+      """
+          Cette méthode indique si le mot cle simple attend une liste (valeur de retour 1)
+          ou s'il n'en attend pas (valeur de retour 0)
+
+          Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
+          Dans le cas sans validateur, l'information est donnée par l'attribut max
+          de la definition du mot cle.
+          Dans le cas avec validateur, il faut combiner l'information précédente avec
+          celle issue de l'appel de la méthode is_list sur le validateur.On utilisera
+          l'operateur ET pour effectuer cette combinaison (AndVal).
+      """
+      is_a_list=0
+      min,max = self.GetMinMax()
+      assert (min <= max)
+      if max > 1 :
+               is_a_list=1
+      # Dans le cas avec validateurs, pour que le mot cle soit considéré
+      # comme acceptant une liste, il faut que max soit supérieur a 1
+      # ET que la méthode is_list du validateur retourne 1. Dans les autres cas
+      # on retournera 0 (n'attend pas de liste)
+      if self.definition.validators :
+         is_a_list= self.definition.validators.is_list() * is_a_list
+      return is_a_list 
+
+  #def get_into(self,liste_courante=None):
+  #    """
+  #        Cette méthode retourne la liste de choix proposée par le mot cle. Si le mot cle ne propose
+  #        pas de liste de choix, la méthode retourne None.
+  #        L'argument d'entrée liste_courante, s'il est différent de None, donne la liste des choix déjà
+  #        effectués par l'utilisateur. Dans ce cas, la méthode get_into doit calculer la liste des choix
+  #        en en tenant compte.
+  #        Cette méthode part du principe que la relation entre into du mot clé et les validateurs est
+  #        une relation de type ET (AndVal).
+  #    """
+  #    if not self.object.definition.validators :
+  #       return self.object.definition.into
+  #    else:
+  #       return self.object.definition.validators.get_into(liste_courante,self.definition.into)
+
+  def has_into(self):
+      """
+          Cette méthode indique si le mot cle simple propose un choix (valeur de retour 1)
+          ou s'il n'en propose pas (valeur de retour 0)
+
+          Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
+          Dans le cas sans validateur, l'information est donnée par l'attribut into
+          de la definition du mot cle.
+         Dans le cas avec validateurs, pour que le mot cle soit considéré
+          comme proposant un choix, il faut que into soit présent OU
+          que la méthode has_into du validateur retourne 1. Dans les autres cas
+          on retournera 0 (ne propose pas de choix)
+      """
+      has_an_into=0
+      if self.definition.into:
+        has_an_into=1
+      elif self.definition.validators :
+         has_an_into= self.definition.validators.has_into()
+      return has_an_into
+
+#  def wait_into(self):
+#      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
+#      prend ses valeurs dans un ensemble discret (into), 0 sinon """
+#      if self.object.definition.into != None :
+#          return 1
+#      else:
+#          return 0
+
+  def GetMinMax(self):
+      """ Retourne les valeurs min et max de la définition de object """
+      return self.object.get_min_max()
+
+  def GetMultiplicite(self):
+      """ A préciser.
+          Retourne la multiplicité des valeurs affectées à l'objet
+          représenté par l'item. Pour le moment retourne invariablement 1.
+      """
+      return 1
+
+  def GetIntervalle(self):
+      """ 
+           Retourne le domaine de valeur attendu par l'objet représenté 
+           par l'item.
+      """
+      return self.object.getintervalle()
+
+  def GetListeValeurs(self) :
+      """ Retourne la liste des valeurs de object """
+      return self.object.get_liste_valeurs()
+    
+  def get_liste_possible(self,listeActuelle=[]):
+      if hasattr(self.definition.validators,'into'):
+        self.get_definition().into=self.definition.validators.into 
+      valeurspossibles = self.get_definition().into
+      # CCAR : Ne serait-il pas preferable d'appeler get_into ?
+      #valeurspossibles=self.get_into(listeActuelle)
+
+      listevalideitem=[]
+      for item in valeurspossibles:
+          encorevalide=self.valide_item(item)
+          if encorevalide :
+             listevalideitem.append(item)
+      # on ne verifie pas la liste des choix si max = 1 
+      # (sinon cela enleve tous les choix possibles)
+      min,max=self.GetMinMax()
+      if max != 1 : 
+         listevalideliste=[]
+         for item in listevalideitem:
+             listetravail=[]
+             for item2 in listeActuelle : listetravail.append(item2)
+             encorevalide=self.valide_liste_partielle(item,listetravail)
+             if encorevalide :
+                listevalideliste.append(item)
+      else :
+         listevalideliste=listevalideitem
+      return listevalideliste
+
+
+  #--------------------------------------------------
+  #
+  # Methodes liees a la validite des valeurs saisies
+  #
+  #---------------------------------------------------
+  # valide_item
+  # valide_liste_partielle
+  # valide_liste_complete
+  # info_erreur_item
+  # info_erreur_liste
+  # IsInIntervalle
+  # isvalid
+
+  def valide_item(self,item):
+      """
+       On fait un try except pour les erreurs de type (exple
+       on rentre 1 pour une chaine de caracteres
+      """
+      valide=1
+      if self.definition.validators :
+         try :
+            valide=self.definition.validators.verif_item(item)
+         except :
+           valide = 0
+      return valide
+     
+  def valide_liste_partielle(self,item,listecourante):
+      valeuravant=self.object.valeur
+      valeur=listecourante
+      valeur.append(item)
+      valeur = tuple(valeur)
+      retour=self.object.set_valeur(valeur)
+      validite=0
+      if self.object.isvalid():
+         validite=1
+      elif self.definition.validators :
+         validite=self.definition.validators.valide_liste_partielle(valeur)
+
+      if validite==0:
+         min,max=self.GetMinMax()
+         if len(valeur) < min :
+           validite=1
+      retour=self.object.set_valeur(valeuravant)
+      return validite 
+
+  def valide_liste_complete (self,valeur):
+      valeuravant=self.object.valeur
+      retour=self.object.set_valeur(valeur)
+      validite=0
+      if self.object.isvalid():
+         validite=1
+      retour=self.object.set_valeur(valeuravant)
+      return validite
+     
+  def info_erreur_item(self) :
+      commentaire=""
+      if self.definition.validators :
+         commentaire=self.definition.validators.info_erreur_item()
+      return commentaire
       
-  def SetText(self, text):
-    try:
-      value = eval(text)
-      self.object.setval(value)
-    except:
-      pass
+  def aide(self) :
+      commentaire=""
+      if self.definition.validators :
+         commentaire=self.definition.validators.aide()
+      return commentaire
+
+  def info_erreur_liste(self) :
+      commentaire=""
+      if self.definition.validators :
+         commentaire=self.definition.validators.info_erreur_liste()
+      return commentaire
+
+  def IsInIntervalle(self,valeur):
+      """ 
+          Retourne 1 si la valeur est dans l'intervalle permis par
+          l'objet représenté par l'item.
+      """
+      return self.object.isinintervalle(valeur)
+
+  def isvalid(self):
+    valide=self.object.isvalid()
+    return self.object.isvalid()
+
+  #--------------------------------------------------
+  #
+  # Autres ...
+  #
+  #---------------------------------------------------
+  # SetText    a priori inutilisee --> commentee
+  # GetIconName
+  # GetText
+  # getval     a  priori inutilisee --> commentee
+  # set_valeur_co
+  # get_sd_avant_du_bon_type
+  # verif      a  priori inutilisee --> commentee
+  # delete_valeur_co
+
+  #def SetText(self, text):
+  #  try:
+  #    value = eval(text)
+  #    self.object.setval(value)
+  #  except:
+  #    pass
 
   def GetIconName(self):
     if self.isvalid():
@@ -1269,7 +380,52 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
     Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
     pointé par self 
     """
-    return self.object.GetText()
+    text= self.object.GetText()
+    return text
+    
+  #def getval(self):
+  #    return self.object.getval()
+
+  def set_valeur_co(self,nom_co):
+      """
+      Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
+      """
+      return self.object.set_valeur_co(nom_co)
+      
+  def get_sd_avant_du_bon_type(self):
+      """
+      Retourne la liste des noms des SD présentes avant l'étape qui contient
+      le MCS pointé par self et du type requis par ce MCS
+      """
+      a=self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type)
+      return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
+                                                               self.object.definition.type)
+
+  #def verif(self):
+  #    pass
+
+  def delete_valeur_co(self,valeur=None):
+      """
+           Supprime la valeur du mot cle (de type CO)
+           il faut propager la destruction aux autres etapes
+      """
+      if not valeur : valeur=self.object.valeur
+      # XXX faut il vraiment appeler del_sdprod ???
+      #self.object.etape.parent.del_sdprod(valeur)
+      self.object.etape.parent.delete_concept(valeur)
+
+  #-----------------------------------------------
+  #
+  # Methodes liees au type de l objet attendu
+  #
+  #-----------------------------------------------
+  # wait_co 
+  # wait_geom
+  # wait_complex
+  # wait_reel
+  # wait_shell
+  # wait_assd
+  # GetType
 
   def wait_co(self):
       """
@@ -1310,84 +466,85 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
       else:
           return 0
 
-  def wait_into(self):
-      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
-      prend ses valeurs dans un ensemble discret (into), 0 sinon """
-      if self.object.definition.into != None :
-          return 1
-      else:
-          return 0
-
   def wait_assd(self):
       """Méthode booléenne qui retourne 1 si l'objet pointé par self
       attend un objet de type ASSD ou dérivé, 0 sinon """
       return self.object.wait_assd()
     
-  def getval(self):
-      return self.object.getval()
-    
-  def GetMinMax(self):
-      """ Retourne les valeurs min et max de la définition de object """
-      return self.object.get_min_max()
-
-  def GetMultiplicite(self):
-      """ A préciser.
-          Retourne la multiplicité des valeurs affectées à l'objet
-          représenté par l'item. Pour le moment retourne invariablement 1.
-      """
-      return 1
-
   def GetType(self):
       """ 
           Retourne le type de valeur attendu par l'objet représenté par l'item.
       """
       return self.object.get_type()
 
-  def GetIntervalle(self):
-      """ 
-           Retourne le domaine de valeur attendu par l'objet représenté 
-           par l'item.
-      """
-      return self.object.getintervalle()
-
-  def IsInIntervalle(self,valeur):
-      """ 
-          Retourne 1 si la valeur est dans l'intervalle permis par
-          l'objet représenté par l'item.
-      """
-      return self.object.isinintervalle(valeur)
-
-  def set_valeur_co(self,nom_co):
-      """
-      Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
-      """
-      return self.object.set_valeur_co(nom_co)
-      
-  def get_sd_avant_du_bon_type(self):
-      """
-      Retourne la liste des noms des SD présentes avant l'étape qui contient
-      le MCS pointé par self et du type requis par ce MCS
-      """
-      return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,
-                                                               self.object.definition.type)
-    
-  def GetListeValeurs(self) :
-      """ Retourne la liste des valeurs de object """
-      return self.object.get_liste_valeurs()
-    
-  def verif(self):
-      pass
-
-  def isvalid(self):
-    return self.object.isvalid()
+  #-----------------------------------------------------
+  #
+  # Methodes liees  a l evaluation de la valeur saisie
+  #
+  #-----------------------------------------------------
+  # eval_valeur
+  # eval_valeur_item
+  # is_CO
+  # traite_reel
 
   def eval_valeur(self,valeur):
       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
       de l'objet pointé par self :
         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
-        - retourne 'valeur' (chaîne de caractères) sinon """
-      return self.object.eval_valeur(valeur)
-
+        - retourne 'valeur' (chaîne de caractères) sinon
+        - retourne None en cas d invalidite
+        - retourne invalide si 1 des objets du tuple l est
+      """
+      validite=1
+      if type(valeur) in (types.ListType,types.TupleType) :
+         valeurretour=[]
+         for item in valeur :
+             newvaleur,validiteitem=self.eval_valeur_item(item)
+             valeurretour.append(newvaleur)
+             if validiteitem == 0:
+               validite=0
+      else :
+         valeurretour,validite= self.eval_valeur_item(valeur)
+      if validite == 0 :
+        valeurretour = None
+      return valeurretour,validite
+
+  def eval_valeur_item(self,valeur):
+      """ Lance l'interprétation de 'valeur' qui doit ne pas etre un tuple 
+         - va retourner la valeur de retour et la validite
+            selon le type de l objet attendu
+          - traite les reels et les parametres 
+      """ 
+      if valeur==None or valeur == "" :
+        return None,0
+      validite=1
+      if self.wait_reel():
+             valeurinter = self.traite_reel(valeur)
+             valeurretour,validite= self.object.eval_valeur(valeurinter)
+      elif self.wait_geom():
+             valeurretour,validite = valeur,1
+      else :
+             valeurretour,validite= self.object.eval_valeur(valeur)
+      if validite == 0:
+        if type(valeur) == types.StringType and self.object.wait_TXM():
+            essai_valeur="'" + valeur + "'"
+            valeurretour,validite= self.object.eval_valeur(essai_valeur)
+      if hasattr(valeurretour,'__class__'):
+         if valeurretour.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
+            validite=1
+      if self.wait_co():
+         try:
+            valeurretour=Accas.CO(valeur)
+         except:
+            valeurretour=None
+            validite=0
+      # on est dans le cas où on a évalué et où on n'aurait pas du
+      if self.object.wait_TXM() :
+         if type(valeurretour) != types.StringType:
+             valeurretour=str(valeur)
+             validite=1
+      return valeurretour,validite
+      
   def is_CO(self,valeur=None):
       """
          Indique si valeur est un concept produit de la macro
@@ -1402,19 +559,30 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
       # et donc pas dans sdprods (resultat d'une exception dans type_sdprod)
       if not valeur:valeur=self.object.valeur
       if valeur in self.object.etape.sdprods:return 1
-      if type(valeur) is not types.ClassType:return 0
+      if type(valeur) is not types.InstanceType:return 0
       if valeur.__class__.__name__ == 'CO':return 1
       return 0
 
-  def delete_valeur_co(self,valeur=None):
+  def traite_reel(self,valeur):
       """
-           Supprime la valeur du mot cle (de type CO)
-           il faut propager la destruction aux autres etapes
+      Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
+      ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
+      ou un EVAL ...
       """
-      if not valeur : valeur=self.object.valeur
-      # XXX faut il vraiment appeler del_sdprod ???
-      #self.object.etape.parent.del_sdprod(valeur)
-      self.object.etape.parent.delete_concept(valeur)
+      valeur = string.strip(valeur)
+      liste_reels = self.get_sd_avant_du_bon_type()
+      if valeur in liste_reels:
+          return valeur
+      if len(valeur) >= 3 :
+          if valeur[0:4] == 'EVAL' :
+              # on a trouvé un EVAL --> on retourne directement la valeur
+              return valeur
+      if string.find(valeur,'.') == -1 :
+          # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
+          return valeur+'.'
+      else:
+          return valeur
+        
 
 import Accas
 treeitem = SIMPTreeItem