Salome HOME
CCAR: Correction du probleme de consommation memoire excessive
[tools/eficas.git] / Editeur / panels.py
1 #@ MODIF panels Editeur  DATE 02/07/2001   AUTEUR D6BHHJP J.P.LEFEBVRE 
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2001  EDF R&D                  WWW.CODE-ASTER.ORG
5 #              SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND
6 #              REDISTRIBUTION OF THIS FILE.
7 # ======================================================================
8 import string
9 import os
10 from Tkinter import *
11 import Pmw
12
13 from widgets import ListeChoix
14
15 SEPARATEUR = '-'*30
16
17 class Panel(Frame) :
18   """
19   Classe servant de classe mère à toutes celles représentant les
20   panneaux à afficher en fonction de la nature de l'objet en cours
21   Elle est toujours dérivée.
22   """
23   def __init__(self,parent,panneau,node) :
24       self.parent=parent
25       self.panneau = panneau
26       self.node=node
27       Frame.__init__(self,self.panneau)
28       self.place(x=0,y=0,relheight=1,relwidth=1)
29       self.creer_boutons()
30       self.init()
31
32   def destroy(self):
33       Frame.destroy(self)
34       self.panneau=None
35       self.parent=None
36       self.node=None
37       # Because on herite de Frame
38       self.master=None
39       # On supprime explicitement les references aux objets Tk
40       self.nb=None
41       self.fr_but=None
42       self.bouton_cata=None
43       self.bouton_doc=None
44       self.bouton_com=None
45       self.bouton_sup=None
46       self.frame_eval=None
47       self.label=None
48       self.frame_boutons=None
49       self.frame_comment=None
50       self.frame_param=None
51       # On termine la suppression de facon brutale (objets Tk et non Tk)
52       for k in self.__dict__.keys():
53          setattr(self,k,None)
54
55   def creer_boutons(self):
56       """
57       Méthode créant les boutons se trouvant dans la partie contextuelle d'EFICAS
58       (à droite sous les onglets )
59       """
60       self.fr_but = Frame(self,height=30)
61       self.fr_but.pack(side='bottom',fill='x')
62       self.bouton_com = Button(self.fr_but,
63                                text = 'Commentariser',
64                                command = self.ajout_commentaire,
65                                width=14)
66       self.bouton_sup = Button(self.fr_but,
67                                text = "Supprimer",
68                                command=self.supprimer,
69                                width=14)
70       self.bouton_doc = Button(self.fr_but,
71                                text="Documentation",
72                                command=self.visu_doc,
73                                width=14)
74       self.bouton_cata = Button(self.fr_but,
75                                 text = "Catalogue",
76                                 command = self.show_catalogue,
77                                 width=14)
78       if self.parent.appli.CONFIGURATION.isdeveloppeur == 'OUI':
79           self.bouton_sup.place(relx=0.25,rely = 0.5,relheight = 0.8,anchor='center')
80           self.bouton_cata.place(relx=0.5,rely = 0.5,relheight = 0.8,anchor='center')
81           self.bouton_doc.place(relx=0.75,rely = 0.5,relheight = 0.8,anchor='center')
82       else:
83           self.bouton_sup.place(relx=0.3,rely = 0.5,relheight = 0.8,anchor='center')
84           self.bouton_doc.place(relx=0.7,rely = 0.5,relheight = 0.8,anchor='center')
85
86   def show_catalogue(self):
87       try:
88           genea = self.node.item.get_genealogie()
89           self.parent.appli.browser_catalogue_objet(genea)
90       except Exception,e:
91           traceback.print_exc()
92       
93   def efface(self):
94       self.node.efface()
95
96 # ------------------------------------------------------------------------
97 #     Méthodes permettant d'ajouter des commentaires, des paramètres
98 #                     et des objets EVAL.
99 #       Ces méthodes sont utilisées par les panneaux des JDC,ETAPE,
100 #                 COMMENTAIRE et PARAMETRE
101 # ------------------------------------------------------------------------
102
103   def ajout_commentaire(self,ind='after'):
104       """
105       Ajoute un commentaire à l'intérieur du JDC :
106       - si ind='after'  : l'ajoute après l'objet courant
107       - si ind='before' : l'ajoute avant.
108       """
109       if self.parent.modified == 'n' : self.parent.init_modif()
110       return self.node.append_brother("COMMENTAIRE",ind)
111     
112   def ajout_commentaire_first(self):
113       """
114       Ajoute un commentaire en début de JDC
115       """
116       if self.parent.modified == 'n' : self.parent.init_modif()
117       return self.node.append_child("COMMENTAIRE",'first')
118
119   def ajout_parametre(self,ind='after'):
120       """
121       Ajoute un parametre à l'intérieur du JDC :
122       - si ind='after'  : l'ajoute après l'objet courant
123       - si ind='before' : l'ajoute avant.
124       """
125       if self.parent.modified == 'n' : self.parent.init_modif()
126       return self.node.append_brother("PARAMETRE",ind)
127     
128   def ajout_parametre_first(self):
129       """
130       Ajoute un parametre en début de JDC
131       """
132       if self.parent.modified == 'n' : self.parent.init_modif()
133       return self.node.append_child("PARAMETRE",'first')
134
135   def ajout_parametre_eval(self,ind='after'):
136       """
137       Ajoute un paramètre EVAL à l'intérieur du JDC :
138       - si ind='after'  : l'ajoute après l'objet courant
139       - si ind='before' : l'ajoute avant.
140       """
141       if self.parent.modified == 'n' : self.parent.init_modif()
142       return self.node.append_brother("PARAMETRE_EVAL",ind)
143     
144   def ajout_parametre_eval_first(self):
145       """
146       Ajoute un paramètre EVAL en début de JDC
147       """
148       if self.parent.modified == 'n' : self.parent.init_modif()
149       return self.node.append_child("PARAMETRE_EVAL",'first')
150     
151 # ------------------------------------------------------------------------
152    
153   def visu_doc(self):
154       """ Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
155         - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
156         - indication du chemin d'accès aux fichiers pdf à revoir : trop statique"""
157       cle_doc = self.node.item.get_docu()
158       if cle_doc == None : return
159       cle_doc = string.replace(cle_doc,'.','')
160       cle_doc = string.replace(cle_doc,'-','')
161       commande = self.parent.appli.CONFIGURATION.exec_acrobat
162       nom_fichier = cle_doc+".pdf"
163       fichier = os.path.abspath(os.path.join(self.parent.appli.CONFIGURATION.path_doc,
164                                        nom_fichier))
165       if os.name == 'nt':
166           os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
167       elif os.name == 'posix':
168           script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
169           pid = os.system(script)
170       
171   def supprimer(self):
172       """
173       Suppression du noeud courant
174       """
175       if self.parent.modified == 'n' : self.parent.init_modif()
176       pere = self.node.parent
177       self.node.delete()
178       
179   def affiche(self):
180       """ Force l'affichage des fenêtres en cours """
181       self.tkraise()
182
183   def selectMC(self,name):
184       """ On retrouve le mot-clé sous le curseur pour affichage du fr """
185       cmd=self.node.item.get_definition()
186       texte_infos = ''
187       for e in cmd.entites.keys() :
188           if e == name :
189               texte_infos=cmd.entites[e].fr
190               break
191       if texte_infos == '' : texte_infos="Pas d'infos disponibles"
192       #EFICAS.affiche_infos(texte_infos)
193       self.parent.appli.affiche_infos(texte_infos)
194
195   def defMC(self,name):
196       """ On ajoute un mot-clé à la commande : subnode """
197       if name == SEPARATEUR:return
198       if self.parent.modified == 'n' : self.parent.init_modif()
199       if name != "COMMENTAIRE":
200           self.node.append_child(name)
201       else :
202           self.ajout_commentaire()    
203
204   def selectCmd(self,name):
205       """ On retrouve la commande sous le curseur pour affichage du fr """
206       if name != 'COMMENTAIRE' and name != SEPARATEUR:
207           #EFICAS.affiche_infos(self.parent.appli.cataitem.d_fils[name].fr)
208           #self.parent.appli.affiche_infos(self.parent.appli.cataitem.d_fils[name].fr)
209           self.parent.appli.affiche_infos(self.parent.jdc.get_cmd(name).fr)
210           
211   def defCmd(self,name):
212       """
213       On ajoute une commande après la commande selectionnée : after
214       ou bien on ajoute un commentaire
215       """
216       if name == SEPARATEUR:return
217       if self.parent.modified == 'n' : self.parent.init_modif()
218       if name != "COMMENTAIRE":
219           new_node = self.node.append_brother(name,'after')
220       else :
221           new_node = self.ajout_commentaire()
222
223   def defCmdFirst(self,name):
224       """ On ajoute une commande ou un commentaire au début du fichier de commandes """
225       if name == SEPARATEUR:return
226       if self.parent.modified == 'n' : self.parent.init_modif()
227       if name != "COMMENTAIRE":
228           new_node = self.node.append_child(name,'first')
229       else :
230           new_node = self.ajout_commentaire_first()
231         
232 class OngletPanel(Panel) :
233   """ Cette classe est virtuelle et doit être dérivée
234       Elle contient les principales méthodes d'affichage des différents onglets"""
235
236   def raisecmd(self,page):
237       self.nb.page(page).focus_set()
238       if page == 'Concept':
239           try:
240               self._any.focus()
241           except:
242               pass
243
244   def affiche(self):
245       page=self.nb.getcurselection()
246       self.nb.page(page).focus_set()
247       if page == 'Concept':self._any.component('entry').focus_set()
248       self.tkraise()
249
250 # ------------------------------------------------------------------------
251 #     Méthodes permettant d'afficher des pages partagées par différents
252 #           types d'objets (règles,mots-clés,concept,...)
253 # ------------------------------------------------------------------------
254
255   def makeConceptPage(self,page):
256       """
257       Crée la page de saisie du nom du concept
258       """
259       self.label = Label(page,text='Nom du concept :')
260       self.label.place(relx=0.1,rely=0.4)
261       self._any = Entry(page,relief='sunken')
262       self._any.place(relx=0.35,rely=0.4,relwidth=0.5)
263       self._any.bind("<Return>",lambda e,s=self:s.execConcept())
264       self._any.insert(0,self.node.item.GetText())
265       type_sd = self.node.item.get_type_sd_prod()
266       if type_sd :
267           txt = "L'opérateur courant retourne un objet de type %s" %type_sd
268           self.label = Label(page, text = txt)
269           self.label.place(relx=0.5,rely=0.55,anchor='n')
270       self._any.focus()
271       # aide associée au panneau
272       bulle_aide="""Tapez dans la zone de saisie le nom que vous voulez donner
273       au concept retoruné par l'opérateur courant et pressez <Return> pour valider"""
274       page.bind("<Button-3>", lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
275       page.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
276         
277   def makeMoclesPage(self,page):
278       """
279       Crée la page qui affiche la liste des mots-clés que l'on peut
280       encore ajouter
281       """
282       genea =self.node.item.get_genealogie()
283       jdc = self.node.item.get_jdc()
284       liste_mc=self.node.item.get_liste_mc_ordonnee(genea,jdc.cata_ordonne_dico)
285       liste_commandes = (("<Enter>",self.selectMC),
286                          ("<Leave>",self.deselectMC),
287                          ("<Double-Button-1>",self.defMC))
288       Liste = ListeChoix(self,page,liste_mc,liste_commandes = liste_commandes,titre = "Mots-clés permis")
289       Liste.affiche_liste()
290       # aide associée au panneau
291       bulle_aide="""Double-cliquez sur le mot-clé que vous voulez ajouter à
292       la commande en cours d'édition"""
293       Liste.MCbox.bind("<Button-3>", lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
294       Liste.MCbox.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
295
296   def makeCommentairePage(self,page):
297       label = Label(page,text = "Insérer un commentaire :")
298       label.grid(column = 0, row = 2)
299       but_avant = Button(page,text = "AVANT",command = lambda s=self :s.ajout_commentaire(ind = 'before'))
300       but_apres = Button(page,text = "APRES",command = self.ajout_commentaire)
301       but_avant.grid(column = 1,row =2)
302       but_apres.grid(column = 1,row =3)
303       
304   def makeCommandePage(self,page):
305       frame1 = Frame(page,height = 20)
306       frame1.pack(side='top',fill='x')
307       label = Label(frame1,text ="La commande choisie sera ajoutée\n APRES la commande courante")
308       label.pack(side='top')
309       frame2 = Frame(page)
310       frame2.pack(side='top',fill='both',expand=1)
311       liste_cmd = self.get_liste_cmd()
312       liste_commandes = (("<Enter>",self.selectCmd),
313                          ("<Leave>",self.deselectCmd),
314                          ("<Double-Button-1>",self.defCmd))
315       Liste = ListeChoix(self,frame2,liste_cmd,liste_commandes = liste_commandes,filtre='oui',titre = "Commandes")
316       Liste.affiche_liste()
317       # aide associée au panneau
318       bulle_aide="""Double-cliquez sur la commande que vous voulez ajouter au jeu de commandes"""
319       Liste.MCbox.bind("<Button-3>", lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
320       Liste.MCbox.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
321
322   def makeJDCPage(self,page):
323       """
324       Crée la page correspondant à un objet de type JDC
325       """
326       liste_cmd = self.get_liste_cmd()
327       liste_commandes = (("<Enter>",self.selectCmd),
328                          ("<Leave>",self.deselectCmd),
329                          ("<Double-Button-1>",self.defCmdFirst))
330       Liste = ListeChoix(self,page,liste_cmd,liste_commandes = liste_commandes,filtre='oui',titre = "Commandes")
331       Liste.affiche_liste()
332        # aide associée au panneau
333       bulle_aide="""Double-cliquez sur la commande que vous voulez ajouter au jeu de commandes"""
334       Liste.MCbox.bind("<Button-3>", lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
335       Liste.MCbox.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
336
337   def makeReglesPage(self,page) :
338       """
339       Crée la page qui affiche la liste des règles avec celle qui ne sont
340       pas respectées en rouge
341       """
342       regles = []
343       regles = self.node.item.get_regles()
344       dictionnaire = self.node.item.get_mc_presents()
345       texte_regles = []
346       l_regles_en_defaut=[]
347       if len(regles) > 0:
348         i = 0
349         for regle in regles :
350           texte_regles.append(regle.gettext())
351           texte,test = regle.verif(dictionnaire)
352           if test == 0 : l_regles_en_defaut.append(i)
353           i = i+1
354       Liste = ListeChoix(self,page,texte_regles,liste_marques=l_regles_en_defaut,active='non',titre="Règles")
355       Liste.affiche_liste()
356       # aide associée au panneau
357       bulle_aide="""Ce panneau contient la liste des règles qui s'appliquent à l'objet
358       en cours d'édition.
359       - en noir : règles valides
360       - en rouge : règles violées"""
361       Liste.MCbox.bind("<Button-3>", lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
362       Liste.MCbox.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
363
364   def makeParamCommentPage_for_etape(self,page):
365       """
366       Crée la page qui offre le choix à l'utilisateur d'ajouter un commentaire
367       ou un paramètre, avant ou après le noeud courant dans l'arbre.
368       Cette page est destinée aux objets de niveau ETAPE cad à toutes les CMD,
369       les commentaires inter commandes et les paramètres
370       """
371       # les frame ...
372       self.frame_comment = Frame(page,bd=1,relief='raised')
373       self.frame_param   = Frame(page,bd=1,relief='raised')
374       self.frame_eval    = Frame(page,bd=1,relief='raised')
375       self.frame_boutons = Frame(page,bd=1,relief='raised')
376       self.frame_comment.place(relx=0,rely=0,relwidth=1,relheight=0.28)
377       self.frame_param.place(relx=0,rely=0.28,relwidth=1,relheight=0.28)
378       self.frame_eval.place(relx=0,rely=0.56,relwidth=1,relheight=0.28)
379       self.frame_boutons.place(relx=0,rely=0.84,relwidth=1,relheight=0.16)
380       # remplissage de la frame commentaire
381       Label(self.frame_comment,text = "Insérer un commentaire :").place(relx=0.1,rely=0.5,anchor='w')
382       but_comment_avant = Button(self.frame_comment,
383                                  text = "AVANT "+self.node.item.get_nom(),
384                                  command = lambda s=self :s.ajout_commentaire(ind = 'before'))
385       but_comment_apres = Button(self.frame_comment,
386                                  text = "APRES "+self.node.item.get_nom(),
387                                  command = self.ajout_commentaire)
388       but_comment_avant.place(relx=0.6,rely=0.3,anchor='w',relwidth=0.3)
389       but_comment_apres.place(relx=0.6,rely=0.7,anchor='w',relwidth=0.3)
390       # remplissage de la frame paramètre
391       Label(self.frame_param,text = "Insérer un paramètre :").place(relx=0.1,rely=0.5,anchor='w')
392       but_param_avant = Button(self.frame_param,
393                                  text = "AVANT "+self.node.item.get_nom(),
394                                  command = lambda s=self :s.ajout_parametre(ind = 'before'))
395       but_param_apres = Button(self.frame_param,
396                                  text = "APRES "+self.node.item.get_nom(),
397                                  command = self.ajout_parametre)
398       but_param_avant.place(relx=0.6,rely=0.3,anchor='w',relwidth=0.3)
399       but_param_apres.place(relx=0.6,rely=0.7,anchor='w',relwidth=0.3)
400       # remplissage de la frame eval
401       Label(self.frame_eval,text="Insérer un paramètre EVAL :").place(relx=0.1,rely=0.5,anchor='w')
402           #Label(self.frame_eval,text='Non encore disponible').place(relx=0.6,rely=0.5,anchor='w')
403       but_eval_avant = Button(self.frame_eval,
404                               text = "AVANT "+self.node.item.get_nom(),
405                               command = lambda s=self :s.ajout_parametre_eval(ind = 'before'))
406       but_eval_apres = Button(self.frame_eval,
407                               text = "APRES "+self.node.item.get_nom(),
408                               command = self.ajout_parametre_eval)
409       but_eval_avant.place(relx=0.6,rely=0.3,anchor='w',relwidth=0.3)
410       but_eval_apres.place(relx=0.6,rely=0.7,anchor='w',relwidth=0.3)      
411       # remplissage de la frame boutons
412       Button(self.frame_boutons,
413              text="Commentariser toute la commande",
414              command = self.comment_commande).place(relx=0.5,rely=0.5,anchor='center')
415     
416   def deselectMC(self,name):
417       #EFICAS.affiche_infos('')
418       self.parent.appli.affiche_infos('')
419     
420   def get_liste_cmd_old(self):
421       listeCmd = self.cata.listCmd()
422       return listeCmd
423
424   def get_liste_cmd(self):
425       listeCmd = self.node.item.object.niveau.definition.get_liste_cmd()
426       return listeCmd
427
428   def deselectCmd(self,name):
429       #EFICAS.affiche_infos('')
430       self.parent.appli.affiche_infos('')
431     
432   def execConcept(self):
433       """
434       Nomme le concept SD retourné par l'étape
435       """
436       if not hasattr(self,'valeur_choisie'):
437           nom = self._any.get()
438       else:
439           nom = self.valeur_choisie.get()
440       nom = string.strip(nom)
441       if nom == '' : return # si pas de nom, on ressort sans rien faire ...
442       if self.parent.modified == 'n' : self.parent.init_modif()
443       # Pourquoi node.etape ???
444       #test,mess = self.node.etape.item.nomme_sd(nom)
445       test,mess = self.node.item.nomme_sd(nom)
446       #EFICAS.affiche_infos(mess)
447       self.parent.appli.affiche_infos(mess)
448       self.node.racine.update()
449   
450   def changed(self):
451       pass
452
453   def comment_commande(self):
454     """
455     Cette méthode a pour but de commentariser la commande pointée par self.node
456     """
457     commande_comment = self.node.item.get_objet_commentarise()
458     #XXX il faudrait ici aussi eviter l'appel à EFICAS
459     self.parent.appli.bureau.JDCDisplay_courant.ReplaceObjectNode(self.node,commande_comment,None)
460     #EFICAS.JDCDisplay_courant.ReplaceObjectNode(self.node,commande_comment,None)
461       
462 class Panel_Inactif(Panel):
463   """
464      Cette classe sert à définir un panneau dans lequel on dit que le noeud 
465      sélectionné n'est pas actif
466   """
467   def __init__(self,parent,panneau,node) :
468       self.parent=parent
469       self.panneau = panneau
470       self.node=node
471       Frame.__init__(self,self.panneau)
472       self.place(x=0,y=0,relheight=1,relwidth=1)
473       self.creer_texte()
474
475   def creer_texte(self):
476       texte = "Le noeud sélectionné ne correspond pas à un objet actif\n"
477       texte = texte + "Seules les commandes placées entre \nDEBUT/POURSUITE et FIN sont actives"
478       longueur = int(self.panneau.winfo_width()*0.8)
479       self.label = Label(self,text=texte,wraplength=longueur,justify='center')
480       self.label.place(relx=0.5,rely=0.4,relwidth=0.8,anchor='center')
481       self.bouton_sup = Button(self,
482                                text = "Supprimer",
483                                command=self.supprimer,
484                                width=14)
485       self.bouton_sup.place(relx=0.5,rely=0.8,anchor='center')
486
487