]> SALOME platform Git repositories - tools/eficas.git/blob - InterfaceTK/plusieursbasepanel.py
Salome HOME
Modif V6_4_°
[tools/eficas.git] / InterfaceTK / plusieursbasepanel.py
1 # -*- coding: utf-8 -*-
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
9 #
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 #
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
18 #
19 #
20 # ======================================================================
21 # Modules Python
22 import string,types,os
23 from Tkinter import *
24 import Pmw
25 from copy import copy,deepcopy
26 import traceback
27
28 # Modules Eficas
29 from Editeur import Objecttreeitem
30 import panels
31 import images
32 from widgets import showinfo
33 from widgets import askopenfilename
34 from widgets import ListeChoix
35 from widgets import FenetreDeSelection
36 from widgets import FenetreDeParametre
37
38 from Noyau.N_CR import justify_text
39 from Ihm.I_LASSD import LASSD
40 from Extensions.parametre import PARAMETRE
41
42 from Editeur.utils import substract_list
43 from plusieurspanel import PLUSIEURS_Panel
44 from uniqueassdpanel import UNIQUE_ASSD_Panel
45
46 import fontes
47 import math
48
49 class PLUSIEURS_BASE_Panel(PLUSIEURS_Panel):
50   """
51   Classe définissant le panel associé aux mots-clés qui demandent
52   à l'utilisateur de donner une liste de valeurs qui ne sont pas
53   à choisir dans une liste discrètes et qui sont de type de base :
54   entier, réel, string,...
55   """
56   def makeValeurPage(self,page):
57       """
58       Crée la page de saisie d'une liste de valeurs à priori quelconques,
59       cad qui ne sont  pas à choisir dans une liste prédéfinie
60       """
61       #print "Methode Utilisée par Salome"
62       # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
63       # et la liste des valeurs déjà affectées à l'objet courant
64       bulle_aide=self.get_bulle_aide()
65       objet_mc = self.node.item.get_definition()
66       aide = self.get_aide()
67       aide = justify_text(texte=aide)
68       min,max = self.node.item.GetMinMax()
69       l_valeurs = self.node.item.GetListeValeurs()
70
71       # création des frames globales
72       self.frame1 = Frame(page,relief='groove',bd=2)
73       self.frame2 = Frame(page)
74       self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.85)
75       self.frame2.place(relx=0.,rely=0.85,relwidth=1,relheight=0.15)
76       self.frame_right = Frame(self.frame1)
77       self.frame_right.place(relx=0.35,rely=0.,relwidth=0.65,relheight=1.)
78
79       # création des frames internes
80       self.frame_valeurs = Frame(self.frame1)
81       self.frame_valeurs.place(relx=0.02,rely=0.05,relwidth=0.35,relheight=0.95)
82       self.frame_boutons_fleches = Frame(self.frame_right)
83       self.frame_boutons_fleches.place(relx=0.,rely=0.2,relwidth=0.2,relheight=0.5)
84       self.frame_choix = Frame(self.frame_right)
85       self.frame_choix.place(relx=0.2,rely=0.2,relwidth=0.7,relheight=0.8)
86       self.frame_aide = Frame(self.frame_right)
87       self.frame_aide.place(relx=0.1,rely=0.8,relwidth=0.8,relheight=0.2)
88       self.frame_boutons = Frame(self.frame2)
89       self.frame_boutons.place(relx=0.2,rely=0.,relwidth=1,relheight=1.)
90       for fram in (self.frame1,self.frame2,self.frame_right,self.frame_valeurs,
91                  self.frame_boutons_fleches,self.frame_choix,self.frame_aide,self.frame_boutons):
92           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
93           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
94
95       # création des objets dans les frames
96       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
97                                  ("<Button-3>",self.deselectValeur),
98                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
99       self.Liste_valeurs=ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
100                                       titre="Valeur(s) actuelle(s)")
101
102       # Création de l'entry ou de la liste des SD
103       # PN : pour ajouter les validators
104       self.label = Label(self.frame_choix,text="Valeur :")
105       self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base)
106       self.label.place(relx=0.05,rely=0.2)
107
108       # Création d'un bouton "Importer ..." et d'un bouton "Parametres" sur le panel.
109       bouton_valeurs_fichier = Button(self.frame_choix,
110                                       text="Importer",
111                                       command=self.select_in_file)
112       bouton_valeurs_fichier.place(relx=0.28,rely=0.4,relwidth=0.6)
113       bouton_parametres = Button(self.frame_choix, text="Parametres", command=self.affiche_parametre)
114       bouton_parametres.place(relx=0.28,rely=0.6,relwidth=0.6)
115       self.ajout_valeurs = None
116
117       # boutons Ajouter et Supprimer
118       self.bouton_add = Button(self.frame_boutons_fleches,
119                           image = images.get_image('arrow_left'),
120                           command = self.add_valeur_plusieurs_base)
121       self.bouton_sup = Button(self.frame_boutons_fleches,
122                           image = images.get_image('arrow_right'),
123                           command = self.sup_valeur_sans_into)
124       self.bouton_add.place(relx=0.3,rely=0.35)
125       self.bouton_sup.place(relx=0.3,rely=0.65)
126       # affichage de l'aide
127       self.frame_aide.update()
128       self.aide = Label(self.frame_aide,
129                         text = aide,
130                         justify='center',
131                         anchor='center',
132                               wraplength=int(self.frame_aide.winfo_width()*0.8))
133       self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
134       self.Liste_valeurs.affiche_liste()
135       if len(l_valeurs) > 0 :
136           liste_marque=l_valeurs[-1]
137           self.Liste_valeurs.surligne(liste_marque)
138           self.selectValeur(liste_marque)
139       # boutons Accepter et Annuler
140       self.bouton_accepter = Button(self.frame_boutons,
141                                text='Valider',
142                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
143       self.bouton_annuler = Button(self.frame_boutons,
144                               text = 'Annuler',
145                               command = self.annule_modifs_valeur)
146       self.bouton_accepter.place(relx=0.2, rely=0.2,relwidth=0.25)
147       self.bouton_annuler.place(relx=0.5, rely=0.2,relwidth=0.25)
148
149   def affiche_parametre(self) :
150       if self.node.item.get_liste_param_possible() != [ ]:
151          txtparam=""
152          for param in self.node.item.get_liste_param_possible():
153             txtparam=txtparam+repr(param)+"\n"
154          if txtparam=="":
155             showerror("Aucun parametre ","Pas de parametre de ce type")
156          else :
157             try :
158                     self.self.fenetreparam.destroy()
159             except:
160                 pass
161             self.fenetreparam=FenetreDeParametre( self, self.node.item, self.parent.appli, txtparam)
162
163   def valid_valeur(self):
164       self.add_valeur_plusieurs_base()
165
166   def add_valeur_plusieurs_base(self,name=None):
167       if name != None :
168          valeur = name
169       else:
170          valeur,validite,commentaire=self.get_valeur()
171          if not validite :
172             self.parent.appli.affiche_infos(commentaire)
173             return
174
175       atraiter=[]
176       if type(valeur)  in (types.ListType,types.TupleType) :
177          indice = 0
178          while (indice < len(valeur)):
179             v=valeur[indice]
180             if self.node.item.wait_complex :
181                if (v== 'RI' or v == 'MP'):
182                   try :
183                      t=tuple([v,valeur[indice+1],valeur[indice+2]])
184                      atraiter.append(t)
185                      indice=indice+3
186                   except :
187                      validite=0
188                      commentaire = "Veuillez entrer le complexe sous forme aster ou sous forme python"
189                      self.parent.appli.affiche_infos(commentaire)
190                      return
191                else :     # ce n'est pas un tuple à la mode aster
192                   atraiter.append(v)
193                   indice = indice + 1
194             else:  # on n'attend pas un complexe
195               atraiter.append(v)
196               indice=indice+1
197       else:
198          atraiter.append(valeur)
199          
200       for valeur in atraiter :
201          encorevalide=self.node.item.valide_item(valeur)
202          if encorevalide :
203             listecourante=self.Liste_valeurs.get_liste()
204             encorevalide=self.node.item.valide_liste_partielle(valeur,listecourante)
205             if not encorevalide : encorevalide = -1
206          self.add_valeur_sans_into(valeur,encorevalide)
207     
208   def select_in_file(self):
209       """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
210       nom_fichier = askopenfilename(title="Choix fichier :")
211
212       if not nom_fichier:
213           return
214
215       try:
216           f = open(nom_fichier, "rb")
217           selection_texte = f.read()
218           f.close()
219           self.ajout_valeurs = FenetreDeSelection(self, 
220                                                   self.node.item,
221                                                   self.parent.appli,
222                                                   titre="Sélection de valeurs",
223                                                   texte=selection_texte)
224       except:
225           traceback.print_exc()
226           showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
227           
228   def get_bulle_aide(self):
229       """
230       Retourne l'aide associée au panneau courant
231       """
232       return """Taper dans la boîte de saisie de droite la valeur que
233       vous voulez affecter au mot-clé simple.
234       - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
235       dans la liste des valeurs que vous voulez affecter au mot-clé simple
236       - Un clic sur une valeur de la liste la sélectionne
237       - Un clic sur la flèche droite ou un double-clic retire la valeur
238       sélectionnée de la liste
239       - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
240       au mot-clé simple
241       - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
242       depuis le dernier clic sur 'Valider'"""
243
244   def get_aide(self):
245       """
246       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
247       que saisit l'utilisateur
248       """
249       commentaire=""
250       mc = self.node.item.get_definition()
251       d_aides = { 'TXM' : 'chaînes de caractères',
252                   'R'   : 'réels',
253                   'I'   : 'entiers',
254                   'C'   : 'complexes'}
255       type = mc.type[0]
256       if not d_aides.has_key(type) : return 'Type de base inconnu'
257       if mc.min == mc.max:
258           commentaire="Une liste de "+d_aides[type]+" de longueur " + `mc.min`  + " est attendue"
259       else :
260           commentaire="Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
261
262       aideval=self.node.item.aide()
263       commentaire=commentaire +"\n"+aideval
264       return commentaire
265
266   def make_entry(self,frame,command,x=0.28,y=0.2):
267       self.entry = Entry(frame,relief='sunken')
268       self.entry.place(relx=0.28,rely=y,relwidth=0.6)
269       self.entry.bind("<Return>",lambda e,c=command:c())
270       self.entry.bind("<KP_Enter>",lambda e,c=command:c())
271       self.entry.focus()
272
273   def get_valeur(self):
274       """
275       Retourne la valeur saisie par l'utilisateur dans self.entry
276       """
277       commentaire = ""
278       if hasattr(self,'entry'):
279          # Traitement d'une entree unique
280          valeurentree = self.entry.get()
281          if (valeurentree == None or valeurentree ==""):
282             return None,0,""
283
284          #On tente une evaluation globale (ne fait pas de vérification de validité
285          #seulement une transformation de la chaine en objet équivalent)
286          valeur,validite=self.node.item.eval_valeur(valeurentree)
287          if valeur == valeurentree:
288              #L'evaluation n'a rien donné : on a toujours la string
289              #on découpe la string sur le séparateur , si c'est possible
290              if valeurentree.find(',') != -1:
291                  valeur=[]
292                  for v in valeurentree.split(','):
293                      vsimple,validite=self.node.item.eval_valeur(v)
294                      valeur.append(vsimple)
295
296          return valeur,validite,commentaire
297
298
299         # if (valeurentree[0] != "(") and (valeurentree.find(',') < len(valeurentree)):
300         #    valeurs=[]
301         #    for v in valeurentree.split(','):
302         #      vsimple,validite=self.node.item.eval_valeur(v)
303               # Pn If ajoute  pour le panneau "double"
304               #if isinstance(vsimple,LASSD) : 
305               #         commentaire = "impossible de mélanger reels et liste prédéfinie"
306               #  validite = 0
307               #         break 
308         #      if validite :
309         #         valeurs.append(vsimple)
310         #      else:
311         #         commentaire = "impossible d'évaluer : %s " %`valeurentree`
312         #         break
313         #    valeur=valeurs
314         # else: 
315         #    valeur,validite=self.node.item.eval_valeur(valeurentree)
316         # if not validite and commentaire == "":
317         #    commentaire = "impossible d'évaluer : %s " %`valeurentree`
318         # return valeur,validite,commentaire
319       #else:
320       #   # Traitement d'une entree de type complexe
321       #   try:
322       #      valeur= (self.typ_cplx.get(),
323       #               string.atof(self.entry1.get()),
324       #               string.atof(self.entry2.get()))
325       #      return valeur,1,""
326       #   except:
327       #      #traceback.print_exc()
328       #      return None,0,"impossible d'évaluer la valeur d'entree"
329
330   def erase_valeur(self):
331       """
332       Efface la valeur donnée par l'utilisateur dans l'entry
333       """
334       if hasattr(self,'entry'):
335          self.entry.delete(0,END)
336       else:
337          self.typ_cplx.set('RI')
338          self.entry1.delete(0,END)
339          self.entry2.delete(0,END)
340
341         
342   def display_valeur(self,val=None):
343       """
344       Affiche la valeur passée en argument dans l'entry de saisie.
345       Par défaut affiche la valeur du mot-clé simple
346       """
347       if not val :
348           valeur = self.node.item.object.getval()
349       else:
350           valeur = val
351       if not valeur : return
352
353       if hasattr(self,'entry'):
354          # Traitement d'une entree unique
355          self.entry.delete(0,END)
356          self.entry.insert(0,str(valeur))
357       else:
358          # Traitement d'une entree de type complexe
359          typ_cplx,x1,x2=valeur
360          self.entry1.delete(0,END)
361          self.entry2.delete(0,END)
362          self.typ_cplx.set(typ_cplx)
363          self.entry1.setentry(x1)
364          self.entry2.setentry(x2)
365
366 class PLUSIEURS_BASE_OR_UNELISTE_Panel(PLUSIEURS_BASE_Panel,UNIQUE_ASSD_Panel):
367
368   def makeValeurPage(self,page):
369       """
370       Crée la page de saisie d'une liste de valeurs à priori quelconques,
371       cad qui ne sont  pas à choisir dans une liste prédéfinie
372       """
373       # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
374       # et la liste des valeurs déjà affectées à l'objet courant
375       bulle_aide=self.get_bulle_aide()
376       objet_mc = self.node.item.get_definition()
377       aide = self.get_aide()
378       aide = justify_text(texte=aide)
379       aide2 = self.get_aide2()
380       aide2 = justify_text(texte=aide2)
381       min,max = self.node.item.GetMinMax()
382       l_valeurs = self.node.item.GetListeValeurs()
383       for i in l_valeurs:
384          if isinstance(i,LASSD) :
385             affiche_entry=l_valeurs
386             l_valeurs=()
387
388       # Il faut traiter ici pour avoir le choix entre une liste
389       # deja constituee (listr8aster) ou manuelle
390
391       # création des frames globales
392       self.frame1 = Frame(page,relief='groove',bd=2)
393       self.frame2 = Frame(page)
394       self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.9)
395       self.frame2.place(relx=0.,rely=0.9,relwidth=1,relheight=0.1)
396
397       # création des frames internes dans frame1
398       self.frame_valeurs = Frame(self.frame1)
399       self.frame_valeurs.place(relx=0.02,rely=0.55,relwidth=0.35,relheight=0.45)
400       self.frame_haut = Frame(self.frame1)
401       self.frame_haut.place(relx=0.02,rely=0.02,relwidth=0.98,relheight=0.45)
402       self.frame_bas = Frame(self.frame1)
403       self.frame_bas.place(relx=0.37,rely=0.55,relwidth=0.63,relheight=0.45)
404
405       # création des frames internes dans frame_right
406       self.frame_fleches = Frame(self.frame_bas)
407       self.frame_fleches.place(relx=0.,rely=0.4,relwidth=0.2,relheight=0.5)
408       self.frame_choix = Frame(self.frame_bas)
409       self.frame_choix.place(relx=0.2,rely=0.1,relwidth=0.75,relheight=1)
410
411       # affichage de l'aide
412       self.aide = Label(self.frame_haut, text = aide, justify='center', anchor='center',)
413       self.aide.place(relx=0.72,rely=0.25,anchor='center',relwidth=1)
414       self.aide2 = Label(self.frame2, text = aide2,)
415       self.aide2.place(relx=0.4,rely=0.01,relwidth=0.6)
416
417       # Création d'un bouton "Importer ..." et d'un bouton "Parametres" sur le panel.
418       bouton_valeurs_fichier = Button(self.frame_choix,
419                                       text="Importer",
420                                       command=self.select_in_file)
421       bouton_valeurs_fichier.place(relx=0.28,rely=0.0,relwidth=0.6)
422       bouton_parametres = Button(self.frame_choix, text="Parametres", command=self.affiche_parametre)
423       bouton_parametres.place(relx=0.28,rely=0.25,relwidth=0.6)
424       self.ajout_valeurs = None
425
426
427       # Création de la liste des SD
428       liste_noms_sd = self.node.item.get_sd_avant_du_bon_type_pour_type_de_base()
429       liste_noms_sd = self.tri(liste_noms_sd)
430       self.listbox = Pmw.ScrolledListBox(self.frame_haut,
431                         items=liste_noms_sd,
432                 labelpos='n',
433                 #label_text="Structures de données du type\n requis parl'objet courant :",
434                 label_text="Listes du type\n requis parl'objet courant :",
435                 listbox_height = 6,
436                 dblclickcommand=lambda s=self,c=UNIQUE_ASSD_Panel.valid_valeur : s.choose_valeur_from_list(c))
437       self.listbox.place(relx=0.00,rely=0.00,relwidth=0.4)
438
439       # On eneleve le label pour gagner de la place 
440       #self.label = Label(self.frame_choix,text="Valeur :")
441       #self.label.place(relx=0.05,rely=0.85)
442       self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base,x=0.28,y=0.55)
443       
444       # boutons Ajouter et Supprimer
445       bouton_add = Button(self.frame_fleches, image = images.get_image('arrow_left'),
446                           command = self.add_valeur_plusieurs_base)
447       bouton_sup = Button(self.frame_fleches, image = images.get_image('arrow_right'),
448                           command = self.sup_valeur_sans_into)
449       bouton_add.place(relx=0.2,rely=0.25)
450       bouton_sup.place(relx=0.2,rely=0.70)
451
452
453       # boutons Accepter et Annuler dans frame2
454       bouton_accepter = Button(self.frame2, text='Valider',
455                                command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
456       bouton_annuler = Button(self.frame2, text = 'Annuler',
457                               command = self.annule_modifs_valeur)
458       for but in (bouton_accepter,bouton_annuler):
459           but.pack(side='left',padx=5)
460
461       # création des objets dans les frames
462       liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
463                                  ("<Button-3>",self.deselectValeur),
464                                  ("<Double-Button-1>",self.sup_valeur_sans_into))
465       self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,
466                                       liste_commandes = liste_commandes_valeurs,
467                                       titre="Valeur(s) non-prédéfinies(s)",
468                                       fonte_titre=None
469                                       )
470
471       for fram in (self.frame1,self.frame2,self.frame_bas,self.frame_haut,self.frame_valeurs,
472                  self.frame_fleches,self.frame_choix):
473           fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide: s.parent.appli.affiche_aide(e,a))
474           fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
475
476       self.Liste_valeurs.affiche_liste()
477       if len(l_valeurs) > 0 :
478           liste_marque=l_valeurs[-1]
479           self.Liste_valeurs.surligne(liste_marque)
480       
481   def get_aide(self):
482       """
483       Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
484       saisies par l'utilisateur
485       """
486       commentaire="Ce motclef accepte soit un nom de liste déja définie soit une liste manuelle de valeurs"
487       return commentaire
488
489   def get_aide2(self):
490       min,max = self.node.item.GetMinMax()
491       aideval=self.node.item.aide()
492       commentaire="min : " + str(min) + ", max : " + str(max)
493       aideval=commentaire + aideval
494       return aideval
495
496   def choose_valeur_from_list(self,command):
497       """
498       Affecte à valeur choisie la sélection courante dans la liste des choix proposés
499       Exécute command
500       """
501       self.Liste_valeurs.liste=[]
502       self.Liste_valeurs.affiche_liste()
503       if len(self.listbox.get()) == 0 : return
504       choix = self.listbox.getcurselection()[0]
505       d={}
506       d["valeurentree"]=choix
507       apply(command,(self,),d)
508      
509
510
511   def tri(self,liste_noms_sd):
512       a=(3+8j)
513       d_types = { 'TXM' : type('A'),
514                   'R'   : type(3.),
515                   'I'   : type(0),
516                   'C'   : type(a)}
517
518       # On enleve seulement ceux qu'on peut
519       # Sur certaines listes, il est possible qu'on ne 
520       # sache pas déterminer le type
521       listefinale=[]
522       typespossibles=self.node.item.object.definition.type
523       typecherche = None
524       for t in typespossibles:
525           if t in d_types.keys() :
526              typecherche = d_types[t]
527              break
528       for liste in liste_noms_sd:
529           valeur,validite=self.node.item.eval_valeur(liste)
530           for mc in valeur.etape.mc_liste :
531               try :
532                  if type(mc.valeur)  in (types.ListType,types.TupleType) :
533                     typeliste=type(mc.valeur[0])
534                  else :
535                     typeliste=type(mc.valeur)
536                  if type(mc.valeur[0]) == typecherche:
537                     listefinale.append(liste)
538               except:
539                  listefinale.append(liste)
540       return listefinale
541