Salome HOME
pour elts de structure
[tools/eficas.git] / Editeur / compomacro.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 os,sys,string
23 import types
24 import Tkinter
25 import Pmw
26 import traceback
27
28 # Modules Eficas
29 import Objecttreeitem
30 import panels
31 import fontes
32 import compooper
33 import convert
34 from widgets import askopenfilename
35 from widgets import Fenetre,FenetreYesNo
36 from widgets import showinfo,showerror
37 from Ihm import CONNECTOR
38
39 #
40 __version__="$Name:  $"
41 __Id__="$Id: compomacro.py,v 1.22 2005/06/10 13:47:49 eficas Exp $"
42 #
43
44 class MACROPanel(panels.OngletPanel):
45   def init(self):
46     nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
47     nb.pack(fill = 'both', expand = 1)
48     self.nb=nb
49     nb.add('Mocles', tab_text='Ajouter mots-clés')
50     typsd=self.node.item.object.get_type_produit()
51     ficini = self.node.item.wait_fichier_init()
52     if typsd != None:
53       nb.add('Concept', tab_text='Nommer concept')
54     if ficini == 1:
55       nb.add('Fichierinit',tab_text = 'Fichier %s' %self.node.item.get_nom())
56     nb.add('Commande', tab_text='Nouvelle Commande')
57     nb.add('Commentaire',tab_text='Paramètre/Commentaire')
58     panneau=Pmw.PanedWidget(nb.page("Mocles"),
59                             orient='horizontal')
60     panneau.add('left',min=0.4,max=0.6,size=0.5)
61     panneau.add('right',min=0.4,max=0.6,size=0.5)
62     panneau.pack(expand=1,fill='both')
63     self.makeCommandePage(nb.page("Commande"))
64     if typsd != None:
65       self.makeConceptPage(nb.page("Concept"))
66     if ficini == 1 :
67       self.makeFichierPage(nb.page('Fichierinit'))
68     self.makeMoclesPage(panneau.pane('left'))
69     self.makeReglesPage(panneau.pane('right'))
70     self.makeParamCommentPage_for_etape(nb.page("Commentaire"))
71     nb.tab('Mocles').focus_set()
72     nb.setnaturalsize()
73     self.affiche()
74
75   def makeFichierPage(self,page):
76     """
77     Affiche la page d'onglet correspondant au changement du fichier
78     dont a besoin la macro
79     """
80     titre = Tkinter.Label(page,text="La commande %s requiert un fichier " %self.node.item.get_nom())
81     titre.place(relx=0.5,rely=0.2,anchor='center')
82     frameMain=Tkinter.Frame(page)
83     frameMain.place(relx=0.5,rely=0.4,anchor='center',relwidth=1.)
84     Tkinter.Label(frameMain,text="Fichier :").pack(side='left',padx=5)
85     self.entry = Tkinter.Entry(frameMain,relief='sunken',bg='white')
86     self.entry.pack(side='left',padx=5,fill='x',expand=1)
87     frameButtons=Tkinter.Frame(page)
88     but1=Tkinter.Button(frameButtons,text='Valider',command = self.change_fichier_init)
89     but2=Tkinter.Button(frameButtons,text='Browse',command = self.browse_fichier_init)
90     but3=Tkinter.Button(frameButtons,text='Annuler',command = self.annule_fichier_init)
91     but1.grid(row=0,column=0,padx=5,pady=5)
92     but2.grid(row=0,column=1,padx=5,pady=5)
93     but3.grid(row=0,column=2,padx=5,pady=5)
94     frameButtons.place(relx=0.5,rely=0.6,anchor='center')
95
96     if hasattr(self.node.item.object,'fichier_ini'):
97       if self.node.item.object.fichier_ini :
98         self.entry.insert(0,self.node.item.object.fichier_ini)
99     self.entry.focus()
100
101   def convert_file(self,file):
102      """
103          Methode pour convertir le fichier file dans le format courant
104      """
105      format=self.parent.appli.format_fichier.get()
106      if convert.plugins.has_key(format):
107          # Le convertisseur existe on l'utilise
108          p=convert.plugins[format]()
109          p.readfile(file)
110          text=p.convert('execnoparseur')
111          if not p.cr.estvide():
112             self.parent.appli.affiche_infos("Erreur à la conversion")
113             Fenetre(self,
114                     titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
115                     texte = str(p.cr))
116             return None
117          return text
118      else:
119          # Il n'existe pas c'est une erreur
120          self.parent.appli.affiche_infos("Type de fichier non reconnu")
121          showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
122          return None
123
124   def change_fichier_init(self,event=None):
125     """ 
126         Effectue le changement de fichier d'initialisation s'il est valide 
127     """
128     new_fic = self.entry.get()
129     if not os.path.isfile(new_fic) :
130       showinfo("Fichier introuvable","Le fichier que vous avez saisi\n"+
131                "n'est pas un nom de fichier valide !")
132       self.parent.appli.affiche_infos("Fichier introuvable")
133       return
134     # On convertit le fichier
135     text=self.convert_file(new_fic)
136     # Si probleme a la lecture-conversion on arrete le traitement
137     if not text:
138        return
139
140     try:
141       self.node.item.object.change_fichier_init(new_fic,text)
142       self.parent.appli.affiche_infos("Fichier %s modifié" %self.node.item.get_nom())
143     except:
144       # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
145       self.parent.appli.affiche_infos("Fichier invalide")
146       l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
147       f=FenetreYesNo(self.parent.appli,titre="Fichier invalide : voulez vous retablir l ancien fichier ?",
148                              texte="Erreur dans l'interprétation du nouveau fichier ...\n\n"+string.join(l),
149                              yes="Retablir",no="Changer")
150       f.wait()
151       reponse=f.result
152       if reponse:
153          # On retablit l'ancien fichier
154          self.entry.delete(0,Tkinter.END)
155          self.node.item.object.restore_fichier_init()
156          self.parent.appli.affiche_infos("Fichier invalide ... Ancien fichier restauré")
157          fic=self.node.item.object.fichier_ini
158          if fic:
159              self.entry.insert(0,fic)
160       else:
161          self.node.item.object.force_fichier_init()
162          self.parent.appli.affiche_infos("Fichier invalide ... Nouveau fichier mémorisé")
163
164   def annule_fichier_init(self,event=None):
165     """ Restaure dans self.entry le nom de fichier_init"""
166     self.entry.delete(0,Tkinter.END)
167     if self.node.item.object.fichier_ini:
168        self.entry.insert(0,self.node.item.object.fichier_ini)
169
170   def browse_fichier_init(self,event=None):
171     """ 
172          Propose à l'utilisateur une Bsf et retourne le fichier 
173          sélectionné dans self.entry 
174     """
175     file = askopenfilename(title="Choix du fichier %s" %self.node.item.get_nom())
176     if file :
177       self.entry.delete(0,Tkinter.END)
178       self.entry.insert(0,file)
179     
180   def update_panel(self):
181     if hasattr(self,"entry"):
182        self.annule_fichier_init()
183     
184 class MACROTreeItem(compooper.EtapeTreeItem):
185   """ Cette classe hérite d'une grande partie des comportements
186       de la classe compooper.EtapeTreeItem
187   """
188   panel=MACROPanel
189
190 class INCLUDETreeItemBase(MACROTreeItem):
191   rmenu_specs=[("View","makeView"),
192                ("Edit","makeEdit"),
193               ]
194
195   def __init__(self,appli, labeltext, object, setfunction):
196     MACROTreeItem.__init__(self,appli, labeltext, object, setfunction)
197
198   def iscopiable(self):
199       """
200       Retourne 1 si l'objet est copiable, 0 sinon
201       """
202       return 0
203
204   def makeEdit(self,appli,node):
205     #print "makeEdit",self.object,self.object.nom
206     #print "makeEdit",self.object.jdc_aux,self.object.jdc_aux.nom
207     #print "makeEdit",self.object.jdc_aux.context_ini
208     if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
209        #L'include n'est pas initialise
210        self.object.build_include(None,"")
211     self.parent_node=node
212     # On cree un nouvel onglet dans le bureau
213     appli.bureau.ShowJDC(self.object.jdc_aux,self.object.jdc_aux.nom,
214                              label_onglet=None,
215                              JDCDISPLAY=macrodisplay.MACRODISPLAY)
216     self.myjdc=appli.bureau.JDCDisplay_courant
217     self.myjdc.fichier=self.object.fichier_ini
218
219   def onClose(self):
220     #print "onClose",self
221     self.appli.bureau.closeJDCDISPLAY(self.myjdc)
222
223   def makeView(self,appli,node):
224     if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
225          showerror("Include vide","L'include doit etre correctement initialisé pour etre visualisé")
226          return
227     nom=self.object.nom
228     if hasattr(self.object,'fichier_ini'):
229        if self.object.fichier_ini is None:
230           nom=nom+' '+"Fichier non défini"
231        else:
232           nom=nom+' '+self.object.fichier_ini
233     macdisp=macrodisplay.makeMacroDisplay(appli,self,nom)
234     CONNECTOR.Connect(self.object.jdc_aux,"close",self.onCloseView,(macdisp,))
235
236   def onCloseView(self,macdisp):
237     #print "onCloseView",self,macdisp
238     macdisp.quit()
239
240 class INCLUDEPanel(MACROPanel):
241   def makeFichierPage(self,page):
242     """
243     Affiche la page d'onglet correspondant au changement du fichier INCLUDE
244     """
245     if not hasattr(self.node.item.object,'fichier_ini'):
246        titre = Tkinter.Label(page,text="L'INCLUDE n'a pas de fichier associé\nIl faut d'abord choisir un numero d'unité " )
247        titre.place(relx=0.5,rely=0.5,anchor='center')
248     else:
249        MACROPanel.makeFichierPage(self,page)
250
251 class INCLUDETreeItem(INCLUDETreeItemBase):
252    panel=INCLUDEPanel
253
254 class POURSUITETreeItem(INCLUDETreeItemBase): 
255   def makeEdit(self,appli,node):
256     if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
257        #La poursuite n'est pas initialisee
258        text="""DEBUT()
259 FIN()"""
260        self.object.build_poursuite(None,text)
261     self.parent_node=node
262     # On cree un nouvel onglet dans le bureau
263     appli.bureau.ShowJDC(self.object.jdc_aux,self.object.jdc_aux.nom,
264                              label_onglet=None,
265                              JDCDISPLAY=macrodisplay.MACRODISPLAY)
266     self.myjdc=appli.bureau.JDCDisplay_courant
267     self.myjdc.fichier=self.object.fichier_ini
268
269   def makeView(self,appli,node):
270     if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
271          showerror("Poursuite vide","Une POURSUITE doit etre correctement initialisée pour etre visualisée")
272          return
273     nom=self.object.nom
274     if hasattr(self.object,'fichier_ini'):
275        if self.object.fichier_ini is None:
276           nom=nom+' '+"Fichier non défini"
277        else:
278           nom=nom+' '+self.object.fichier_ini
279     macdisp=macrodisplay.makeMacroDisplay(appli,self,nom)
280     CONNECTOR.Connect(self.object.jdc_aux,"close",self.onCloseView,(macdisp,))
281
282 class INCLUDE_MATERIAUTreeItem(INCLUDETreeItemBase):
283   rmenu_specs=[("View","makeView"),
284               ]
285   def iscopiable(self):
286       """
287       Retourne 1 si l'objet est copiable, 0 sinon
288       """
289       return 1
290
291
292 def treeitem(appli, labeltext, object, setfunction=None):
293    """ Factory qui retourne l'item adapté au type de macro : 
294        INCLUDE, POURSUITE, MACRO
295    """
296    if object.nom == "INCLUDE_MATERIAU":
297       return INCLUDE_MATERIAUTreeItem(appli, labeltext, object, setfunction)
298    elif object.nom == "INCLUDE":
299       return INCLUDETreeItem(appli, labeltext, object, setfunction)
300    elif object.nom == "POURSUITE":
301       return POURSUITETreeItem(appli, labeltext, object, setfunction)
302    else:
303       return MACROTreeItem(appli, labeltext, object, setfunction)
304
305 import Accas
306 objet=Accas.MACRO_ETAPE
307     
308 import macrodisplay