Salome HOME
CCAR: merge de la version de developpement V1_12a2 dans la branche principale
[tools/eficas.git] / Editeur / bureau.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 """
22    Ce module contient la classe BUREAU qui gere les JDC ouverts
23 """
24 # Modules Python
25 import os,string,sys
26 import traceback
27 import Pmw
28 from widgets import askopenfilename,asksaveasfilename
29 from widgets import showinfo,askyesno,showerror
30
31 # Modules Eficas
32 import splash
33 import prefs
34 import convert
35 import generator
36 import AIDE
37 import os
38 from jdcdisplay import JDCDISPLAY
39 from utils import extension_fichier,stripPath,save_in_file
40 from widgets import Fenetre,Ask_Format_Fichier,FenetreSurLigneWarning
41 from fenetre_mc_inconnus import fenetre_mc_inconnus
42 from Ihm import CONNECTOR
43 from Traducteur import traduitV7V8 
44
45 import comploader
46
47 class BUREAU:
48    menu_defs=[
49               ('Fichier',[
50                            ('Nouveau','newJDC','<Control-n>'),
51                            ('Ouvrir','openJDC','<Control-o>'),
52                            ('Enregistrer','saveJDC','<Control-e>'),
53                            ('Enregistrer sous','saveasJDC','<Control-s>'),
54                            None,
55                            ('Fermer','closeJDC','<Control-f>'),
56                            ('Quitter','exitEFICAS','<Control-q>'),
57                          ]
58               ),
59               ('Edition',[
60                            ('Copier','copy','<Control-c>'),
61                            ('Couper','cut','<Control-x>'),
62                            ('Coller','paste','<Control-v>'),
63                          ]
64               ),
65               ('Jeu de commandes',[
66                                    ('Rapport de validation','visuCRJDC','<Control-r>'),
67                                    ('Fichier à plat','visu_a_plat','<Control-p>'),
68                                    ('Fichier .py','visuJDC_py'),
69                                    ('Fichier source','visu_txt_brut_JDC','<Control-b>'),
70                                    ('Paramètres Eficas','affichage_fichier_ini'),
71                                    ('Mots-clés inconnus','mc_inconnus'),
72                                   ]
73               ),
74               ('Traduction',[
75                              ('Traduction v7 en v8','TraduitFichier','<Control-t>','Ctrl+T')
76                             ]
77               ),
78               ('Aide',[
79                         ('Aide EFICAS','aideEFICAS'),
80                       ]
81               ),
82              ]
83
84    button_defs  =      (('New24',"newJDC","Création d'un nouveau fichier",'always'),
85                         ('Open24',"openJDC","Ouverture d'un fichier existant",'always'),
86                         ('Save24',"saveJDC","Sauvegarde du fichier courant",'always'),
87                         ('Fermer24',"closeJDC","Fermeture du fichier courant",'always'),
88                         ('Zoom24',"visuJDC","Visualisation du fichier de commandes",'always'),
89                         None,
90                         ('Copy24',"copy","Copie l'objet courant",'jdc'),
91                         ('Cut24',"cut","Coupe l'objet courant",'jdc'),
92                         ('Paste24',"paste","Colle l'objet copié après l'objet courant",'jdc'),
93                         None,
94                         ('Delete24',"delete","Supprime l'objet courant",'jdc'),
95                         ('Help24',"view_doc","Documentation de l'objet courant",'jdc')
96                        )
97    try:
98       menu_defs=prefs.menu_defs['bureau']
99    except:
100       pass
101    try:
102       button_defs=prefs.button_defs['bureau']
103    except:
104       pass
105
106    def __init__(self,appli,parent):
107       self.parent=parent
108       self.appli=appli
109       if self.appli.test == 0 :
110          splash._splash.configure(text = "Création du bureau")
111       self.nb = Pmw.NoteBook(self.parent,raisecommand=self.selectJDC)
112       self.nb.pack(fill='both',expand=1)
113       self.JDCDisplay_courant=None
114       self.fileName=None
115       self.liste_JDCDisplay=[]
116       comploader.charger_composants()
117       self.cree_cataitem()
118       self.text_reel=""
119       self.initialdir = self.appli.CONFIGURATION.initialdir
120
121    def cree_cataitem(self):
122       """
123           On récupère dans l'appli_composant readercata les variables 
124           qui servent par la suite pour la création des JDC
125       """
126       self.cataitem=self.appli.readercata.cataitem
127       self.cata=self.appli.readercata.cata
128       self.cata_ordonne_dico=self.appli.readercata.cata_ordonne_dico
129       self.code=self.appli.readercata.code
130       self.version_code=self.appli.readercata.version_code
131       self.fic_cata=self.appli.readercata.fic_cata
132
133    def selectJDC(self,event=None):
134       """
135           Cette méthode est appelée chaque fois que l'on sélectionne 
136           l'onglet d'un JDC dans le NoteBook des JDC.
137           Elle permet de stocker dans les variable self.JDC et 
138           self.JDCDisplay_courant les valeurs concernant le JDC courant
139       """
140       if len(self.liste_JDCDisplay) == 0 : return
141       #if self.JDCDisplay_courant : self.JDCDisplay_courant.jdc.unset_context()
142       numero_jdc = self.nb.index(self.nb.getcurselection())
143       self.JDCDisplay_courant.unselect()
144       self.JDCDisplay_courant = self.liste_JDCDisplay[numero_jdc]
145       self.JDC = self.JDCDisplay_courant.jdc
146       self.JDCName = self.JDC.nom
147       self.JDCDisplay_courant.select()
148       #print "selectJDC",numero_jdc,self.JDCDisplay_courant,self.JDCName
149
150
151    def newJDC_include(self,event=None):
152       """
153           Initialise un nouveau JDC include vierge
154       """
155       import Extensions.jdc_include
156       JdC_aux=Extensions.jdc_include.JdC_include
157
158       self.appli.statusbar.reset_affichage_infos()
159
160       CONTEXT.unset_current_step()
161       jaux=self.cata[0].JdC(procedure="",appli=self.appli,
162                          cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
163                          rep_mat=self.appli.CONFIGURATION.rep_mat,
164                          )
165       jaux.analyse()
166
167       J=JdC_aux(procedure="",appli=self.appli,
168                          cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
169                          jdc_pere=jaux,
170                          rep_mat=self.appli.CONFIGURATION.rep_mat,
171                          )
172       J.analyse()
173       self.JDCName=J.nom
174       self.fileName=None
175       self.ShowJDC(J,self.JDCName)
176       self.appli.toolbar.active_boutons()
177       return J
178
179    def newJDC(self,event=None):
180       """
181           Initialise un nouveau JDC vierge
182       """
183       self.appli.statusbar.reset_affichage_infos()
184
185       CONTEXT.unset_current_step()
186       J=self.cata[0].JdC(procedure="",appli=self.appli,
187                          cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
188                          rep_mat=self.appli.CONFIGURATION.rep_mat,
189                          )
190       J.analyse()
191       self.JDCName=J.nom
192       self.fileName=None
193       self.ShowJDC(J,self.JDCName)
194       self.appli.toolbar.active_boutons()
195       return J
196
197    def ShowJDC(self,JDC,nom,label_onglet=None,JDCDISPLAY=JDCDISPLAY,enregistre="non"):
198       """
199           Lance l'affichage du JDC cad création du JDCDisplay
200           Rajoute le JDCDisplay à la liste des JDCDisplay si label_onglet == None cad si on crée
201           bien un nouveau JDCDisplay et non si on remplace (renommage de l'onglet)
202       """
203       self.JDC=JDC
204       self.JDCName = self.JDC.nom = nom
205       if label_onglet == None :
206           # On veut un nouvel onglet
207           label_onglet = self.GetLabelJDC()
208           self.nb.add(label_onglet,tab_text = nom,tab_width=20)
209           new = 'oui'
210       else :
211           new = 'non'
212       self.JDCDisplay_courant=JDCDISPLAY(self.JDC,nom,appli=self.appli,parent=self.nb.page(label_onglet))
213       if new == 'oui':
214           self.liste_JDCDisplay.append(self.JDCDisplay_courant)
215       self.JDCDisplay_courant.modified='n'
216       if enregistre != "non" :
217          self.JDCDisplay_courant.fichier=self.fileName
218       else :
219          self.initialdir = self.appli.CONFIGURATION.rep_user
220       self.nb.selectpage(label_onglet)
221       self.nb.setnaturalsize()
222       self.nb.bind_all("<Key-Next>",lambda e,s=self:s.selectArbreDown())
223       self.nb.bind_all("<Key-Prior>",lambda e,s=self:s.selectArbreUp())
224       self.nb.bind_all("<Insert>",lambda e,s=self:s.deplieReplieNode())
225       texte = "Jeu de commandes :" + self.JDCName+" ouvert"
226       CONNECTOR.Connect(JDC,"close",self.onClose,(self.JDCDisplay_courant,))
227       self.appli.affiche_infos(texte)
228
229    def onClose(self,jdcdisplay):
230       #print "onClose",jdcdisplay
231       self.closeJDCDISPLAY(jdcdisplay)
232
233    def closeJDCDISPLAY(self,jdc):
234       """
235         Ferme le jdcdisplay spécifié par l'argument jdc
236       """
237       if jdc is self.JDCDisplay_courant:
238          # on ferme le jdcdisplay courant
239          self.closeSelectedJDC()
240       else:
241          # on ferme un autre jdcdisplay que le courant
242          old_JDCDisplay=self.JDCDisplay_courant
243          old_page=self.nb.getcurselection()
244
245          self.JDCDisplay_courant=jdc
246          self.JDC=jdc.jdc
247          numero_jdc=self.liste_JDCDisplay.index(jdc)
248          self.nb.selectpage(numero_jdc)
249          #print numero_jdc
250       
251          self.closeSelectedJDC()
252          self.JDCDisplay_courant=old_JDCDisplay
253          self.JDC=old_JDCDisplay.jdc
254          self.nb.selectpage(old_page)
255
256    def closeJDC (self,event=None) :
257       """
258           Ferme le JDC associé au JDCDISPLAY selectionné
259       """
260       if self.JDCDisplay_courant :
261          self.JDCDisplay_courant.jdc.close()
262
263    def closeSelectedJDC (self) :
264       """
265       Ferme le JDC courant et détruit l'onglet associé dans le notebook self.nb
266       """
267       if self.JDCDisplay_courant.modified == 'o' :
268           message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
269           reponse = askyesno(title="Sauvegarde du jdc courant",
270                              message=message)
271           if reponse :
272               test = self.saveJDC()
273               if test == 0 :
274                   self.appli.affiche_infos("Sauvegarde impossible")
275                   return
276
277       CONNECTOR.Disconnect(self.JDCDisplay_courant.jdc,"close",self.onClose,(self.JDCDisplay_courant,))
278       self.JDCDisplay_courant.supprime()
279       self.JDCDisplay_courant.jdc.supprime()
280       self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
281       # Active le mecanisme de selection du notebook (selectJDC)
282       self.nb.delete(self.nb.getcurselection())
283
284       try:
285           index = self.nb.index(self.nb.getcurselection())
286           self.JDCDisplay_courant = self.liste_JDCDisplay[index]
287           self.JDC = self.JDCDisplay_courant.jdc
288       except:
289           self.JDC = None
290           self.JDCDisplay_courant = None
291           self.appli.toolbar.inactive_boutons()
292
293    def visuCRJDC(self,event=None):
294       return self.visuCR(mode='JDC')
295
296    def visuCR(self,mode):
297       """
298       Méthode permettant l'affichage du rapport de validation
299       """
300       if mode == 'JDC':
301           if not hasattr(self,'JDC') : return
302           if self.JDC == None : return
303           titre="rapport de validation du jeu de commandes courant"
304           cr = self.JDC.report()
305           #self.update_jdc_courant()
306       elif mode == 'CATA':
307           from Noyau.N_CR import CR
308           cr = CR()
309           cr.debut = "Début rapport de validation du catalogue"
310           cr.fin = "Fin rapport de validation du catalogue"
311           titre="rapport de validation du catalogue"
312           if hasattr(self,'cata_ordonne_cr') :
313               cr.add(self.cata_ordonne_cr)
314           if hasattr(self,'cata_dev_ordonne_cr') :
315               cr.add(self.cata_dev_ordonne_cr)
316           for cata in self.cata:
317               if hasattr(cata,'JdC'):
318                   cr.add(cata.JdC.report())
319       texte_cr = str(cr)
320       self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
321
322    def openJDC(self,event=None,file=None,units=None,enregistre="oui"):
323       """
324           Demande à l'utilisateur quel JDC existant il veut ouvrir
325       """
326       if self.code == 'ASTER':
327           filetypes = ( ("format "+self.appli.format_fichier.get(), ".com*"),("Tous",'*'))
328       elif self.code == 'HOMARD' :
329           filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),("Tous",'*'))
330       else:
331           filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
332       if not hasattr(self,'initialdir'):
333          self.initialdir = self.appli.CONFIGURATION.initialdir
334
335       if not file :
336           file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
337                                  defaultextension=".comm",
338                                  filetypes = filetypes,
339                                  initialdir = self.initialdir)
340       if file :
341           self.fileName = file
342           e=extension_fichier(file)
343           self.JDCName=stripPath(file)
344           self.initialdir = os.path.dirname(os.path.abspath(file))
345       else :
346           return
347
348       format=self.appli.format_fichier.get()
349       # Il faut convertir le contenu du fichier en fonction du format
350       if convert.plugins.has_key(format):
351          # Le convertisseur existe on l'utilise
352          p=convert.plugins[format]()
353          p.readfile(file)
354          text=p.convert('exec',self.appli)
355          if not p.cr.estvide(): 
356             self.appli.affiche_infos("Erreur à la conversion")
357             Fenetre(self.appli,
358                     titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
359                     texte = str(p.cr)).wait()
360             return
361          if enregistre == "oui" :
362             self.appli.listeFichiers.aOuvert(file)
363       else:
364          # Il n'existe pas c'est une erreur
365          self.appli.affiche_infos("Type de fichier non reconnu")
366          showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
367          return
368
369       # On se met dans le repertoire ou se trouve le fichier de commandes
370       # pour trouver les eventuels fichiers include ou autres
371       # localises a cote du fichier de commandes
372       os.chdir(self.initialdir)
373       CONTEXT.unset_current_step()
374       J=self.cata[0].JdC(procedure=text,appli=self.appli,
375                          cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
376                          nom = self.JDCName,
377                          rep_mat=self.appli.CONFIGURATION.rep_mat,
378                          )
379       if units is not None:
380          J.recorded_units=units
381          J.old_recorded_units=units
382
383       J.analyse()
384       txt_exception = J.cr.get_mess_exception()
385       if txt_exception :
386           # des exceptions ont été levées à la création du JDC 
387           # --> on affiche les erreurs mais pas le JDC
388           self.JDC=J
389           self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
390           if self.appli.test == 0 :
391              showerror("Erreur fatale au chargement d'un fichier",txt_exception)
392       else:
393           self.ShowJDC(J,self.JDCName,enregistre=enregistre)
394           self.appli.toolbar.active_boutons()
395           # si le JDC ne contient rien (vide), on retourne ici
396           if len(self.JDC.etapes) == 0 : return
397           # dans le cas où le JDC est invalide, on affiche son CR
398           if not self.JDC.isvalid():
399              self.appli.top.update()
400              self.visuCR(mode='JDC')
401       return J
402
403    def deplieReplieNode(self):
404        self.JDCDisplay_courant.tree.tree.deplieReplieNode()
405
406    def selectArbreDown(self):
407        self.JDCDisplay_courant.tree.tree.canvas.focus_set()
408        self.JDCDisplay_courant.tree.tree.mot_down_force()
409
410    def selectArbreUp(self):
411        self.JDCDisplay_courant.tree.tree.canvas.focus_set()
412        self.JDCDisplay_courant.tree.tree.mot_up_force()
413
414    def GetLabelJDC(self,nb_jdc = 'absent'):
415       """
416       Retourne le label de l'onglet du NoteBook associé au JDC à afficher
417       """
418       if nb_jdc == 'absent':
419           nb_jdc = len(self.nb.pagenames())
420       nb_jdc = nb_jdc+1
421       label_onglet = 'JDC'+`nb_jdc`
422       if label_onglet not in self.nb.pagenames() :
423           return label_onglet
424       else :
425           return self.GetLabelJDC(nb_jdc)
426
427    def saveasJDC(self,event=None):
428       """ 
429            Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
430            donner le nom du fichier de sauvegarde 
431       """
432       self.saveJDC(echo='oui')
433
434    def saveJDC(self,echo='non'):
435       """ 
436           Sauvegarde le JDC courant.
437           Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
438
439             - Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il 
440                             veut sauver le JDC
441             - Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
442       """
443       ok = 0
444       if not hasattr(self,'JDC') : return 0
445       format=self.appli.format_fichier.get()
446       if generator.plugins.has_key(format):
447          # Le generateur existe on l'utilise
448          g=generator.plugins[format]()
449          jdc_formate=g.gener(self.JDC,format='beautifie')
450          if format == 'homard':
451             self.jdc_homard=g.get_homard()
452          if not g.cr.estvide():
453             self.appli.affiche_infos("Erreur à la generation")
454             showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
455             return
456       else:
457          # Il n'existe pas c'est une erreur
458          self.appli.affiche_infos("Format %s non reconnu" % format)
459          showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
460          return
461       self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
462
463       if echo =='oui' or self.JDCDisplay_courant.fichier == None:
464          ok = self.asknomsauvegardeJDC()
465       elif self.JDCDisplay_courant.fichier != None :
466          # le JDC a déjà un nom : on sauvegarde directement sans demander
467          # un autre nom au développeur
468          if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini,self.appli.dir) :
469               showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
470               #return 0
471               ok = 0
472          else :
473               if self.appli.format_fichier.get() == 'homard':
474                   self.save_homard(self.JDCDisplay_courant.fichier,self.jdc_homard)
475               self.JDCDisplay_courant.stop_modif()
476               self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
477               ok = 1
478
479       if ok and hasattr( self.appli, 'salome'):
480          # eficas a été lancé à partir deSalome
481          #1)ajout dans l'arbre d'étude du nom du jdc
482          ok, msg = self.appli.addJdcInSalome( self.JDCDisplay_courant.fichier )
483
484          #2)CS_pbruno ??
485          from panelsSalome import SALOME_UNIQUE_BASE_Panel
486          if len(SALOME_UNIQUE_BASE_Panel.dict_fichier_unite) > 0 :
487             print 'CS_pbruno if len(SALOMchier_unite) > 0 :???????'
488             self.appli.creeConfigTxt( self.appli.CONFIGURATION.initialdir, SALOME_UNIQUE_BASE_Panel.dict_fichier_unite )
489
490          #3)création/mise à jours d'un maillage dans Salome
491          self.appli.createOrUpdateMesh()
492       return ok
493
494    def asknomsauvegardeJDC(self):
495       """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
496       titre = "Sauvegarde d'un fichier de commandes "+self.code
497       if self.code == 'ASTER':
498           defext = ".comm"
499           filtyp = ( ("ASTER", ".comm"),)
500       else :
501           defext = ".py"
502           filtyp = ( (self.code, ".py"),)
503       sauvegarde = asksaveasfilename(title=titre,
504                                      defaultextension=defext,
505                                      filetypes = filtyp,
506                                      initialdir = self.initialdir)
507                             #initialdir = self.appli.CONFIGURATION.initialdir)
508                             #initialdir = self.appli.CONFIGURATION.rep_user)
509       if sauvegarde :
510           if not save_in_file(sauvegarde,self.jdc_fini,None) :
511               showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
512               return 0
513           else :
514               if self.appli.format_fichier.get() == 'homard':
515                   self.save_homard(sauvegarde,self.jdc_homard)
516               self.JDCDisplay_courant.stop_modif()
517               self.appli.affiche_infos("Sauvegarde effectuée")
518               if sauvegarde != self.JDCDisplay_courant.fichier :
519                   # l'utilisateur a sauvegardé le JDC sous un autre nom
520                   self.JDCDisplay_courant.fichier = sauvegarde
521                   self.JDCName = self.JDC.nom = stripPath(sauvegarde)
522                   self.JDC.changefichier(sauvegarde)
523                   self.changeNomPage()
524               return 1
525       else :
526           return 0
527
528    def changeNomPage(self):
529       """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
530           et recrée un autre onglet à la même place avec le bon nom 
531       """
532       nom = self.JDCName
533       self.JDCDisplay_courant.jdc.nom = nom
534       nom_page = self.nb.getcurselection()
535       num_page = self.nb.index(nom_page)
536       tab = self.nb.tab(num_page)
537       tab.configure(text = nom)
538
539    def exitEFICAS(self,event=None):
540       """
541           Permet de sortir d'EFICAS en demandant à l'utilisateur
542           s'il veut sauvegarder les modifications en cours
543       """
544       liste = self.GetListeJDCaSauvegarder()
545       if liste != [] :
546           # Certains fichiers n'ont pas été sauvegardés ...
547           if askyesno("Enregistrer modifications","Enregistrer les modifications ?") :
548               test = self.saveall(liste)
549               if test != 1 :
550                   return
551       if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
552           for JDCDisplay in self.liste_JDCDisplay:
553               JDCDisplay.jdc.supprime()
554           self.appli.quit()
555           return
556
557    def GetListeJDCaSauvegarder(self) :
558       """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
559       if not self.JDCDisplay_courant : return []
560       if len(self.liste_JDCDisplay) == 0 : return l
561       l = []
562       for JDCDisplay in self.liste_JDCDisplay:
563           if JDCDisplay.modified == 'o' :
564               l.append(JDCDisplay)
565       return l
566
567    def copy(self,event=None):
568       """
569           Lance la copie sur le JDC courant
570       """
571       if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
572
573    def paste(self,event=None):
574       """
575            Lance le collage sur le JDC courant
576       """
577       if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
578
579    def cut(self,event=None):
580       """
581          Lance le cut sur le JDC courant
582       """
583       if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
584
585    def delete(self):
586       """
587           Lance la suppression du noeud courant
588       """
589       if not self.JDCDisplay_courant : return
590       self.JDCDisplay_courant.init_modif()
591       self.JDCDisplay_courant.node_selected.delete()
592
593    def visuJDC_py(self,event=None):
594       """ 
595           Méthode permettant d'afficher dans une fenêtre à part l'écho au 
596           format python du jdc courant 
597       """
598       if not hasattr(self,'JDC') : return
599       jdc_fini = self.get_text_JDC('python')
600       if jdc_fini == None : return
601       Fenetre(self.appli,
602               titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
603               texte = jdc_fini)
604
605    def visuJDC(self):
606       """ 
607           Méthode permettant d'afficher dans une fenêtre à part l'écho au 
608           format .comm ou .py du jdc courant 
609       """
610       if not hasattr(self,'JDC') : return
611       titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
612       format=self.appli.format_fichier.get()
613       self.jdc_fini = self.get_text_JDC(format)
614       if self.jdc_fini == None : return
615       self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
616
617    def get_text_JDC(self,format):
618       if generator.plugins.has_key(format):
619          # Le generateur existe on l'utilise
620          g=generator.plugins[format]()
621          jdc_formate=g.gener(self.JDC,format='beautifie')
622          if not g.cr.estvide():
623             self.appli.affiche_infos("Erreur à la generation")
624             showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
625             return
626          else:
627             return jdc_formate
628       else:
629          # Il n'existe pas c'est une erreur
630          self.appli.affiche_infos("Format %s non reconnu" % format)
631          showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
632          return
633
634    def view_doc(self):
635       """
636           Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
637           - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
638           - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
639       """
640       if not self.JDCDisplay_courant : return
641       try:
642           cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
643           if cle_doc == None : return
644           cle_doc = string.replace(cle_doc,'.','')
645           cle_doc = string.replace(cle_doc,'-','')
646           commande = self.appli.CONFIGURATION.exec_acrobat
647           nom_fichier = cle_doc+".pdf"
648           fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,nom_fichier))
649           if os.name == 'nt':
650               os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
651           elif os.name == 'posix':
652               script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
653               pid = os.system(script)
654       except AttributeError:
655           traceback.print_exc()
656           pass
657
658    def visu_a_plat(self,event=None):
659       """ 
660           Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant 
661       """
662       if not hasattr(self,'JDC') : return
663       titre = 'fichier '+ self.JDCName + ' à plat '
664       self.jdc_fini = self.get_text_JDC('aplat')
665       if self.jdc_fini == None : return
666       self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
667
668    def visu_txt_brut_JDC(self,event=None):
669       """
670            Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
671       """
672       if not hasattr(self,'JDC') : return
673       titre = "fichier de commandes utilisateur"
674       #texte = self.JDC.procedure
675       #if texte == None:
676       if self.JDCDisplay_courant.fichier == None:
677             self.appli.affiche_infos("Pas de fichier initial")
678             showerror("Impossible de visualiser le fichier initial",
679                       "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC")
680             return
681       os.chdir(self.appli.dir)
682       f=open(self.JDCDisplay_courant.fichier,'r')
683       texte=f.read()
684       f.close()
685       self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
686
687    def affichage_fichier_ini(self):
688       """
689            Affichage des valeurs des paramètres relus par Eficas
690       """
691       self.appli.CONFIGURATION.affichage_fichier_ini()
692
693    def saveall(self,liste):
694       """ 
695            Sauvegarde tous les JDC contenus dans liste 
696       """
697       test = 1
698       for JDCDisplay in liste :
699           self.JDCDisplay_courant=JDCDisplay
700           self.JDC = JDCDisplay.jdc
701           test = test * self.saveJDC(echo = 'non')
702       return test
703
704    def save_homard(self,nom,texte):
705        file_homard=nom+'.conf_homard'
706        try:
707            f=open(file_homard,'w')
708            for ligne in texte:
709                f.write(ligne)
710                f.write('\n')
711            f.close()
712        except:
713            print "Pb a la sauvegarde sous le format homard"
714        if hasattr( self.appli, 'salome'):
715            import eficasEtude
716            self.appli.salome.rangeInStudy(file_homard,"_CONF")
717
718 # ---------------------------------------------------------------------------
719 #                             Méthodes liées aux mots-clés inconnus
720 # ---------------------------------------------------------------------------
721
722    def mc_inconnus(self):
723       l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
724       o = fenetre_mc_inconnus(l_mc)
725       l = o.wait_new_list()
726       #print "mc_inconnus_new_list: ",l
727       #CCAR: Il n' y a pas de retour vers le JDC
728
729    def aideEFICAS(self,event=None):
730       AIDE.go(master=self.parent)
731
732    def update_jdc_courant(self):
733       self.JDCDisplay_courant.update()
734
735    def TraduitFichier(self):
736       directory = self.appli.CONFIGURATION.rep_user
737       FichieraTraduire = askopenfilename(title="Nom du  Fichier à Traduire",
738                                  defaultextension=".comm",
739                                  initialdir = directory 
740                                  )
741       if (FichieraTraduire == "" or FichieraTraduire == () ) : return
742       i=FichieraTraduire.rfind(".")
743       Feuille=FichieraTraduire[0:i]
744       FichierTraduit=Feuille+"v8.comm"
745       log=self.initialdir+"/convert.log"
746       os.system("rm -rf "+log)
747       os.system("rm -rf "+FichierTraduit)
748       Pmw.showbusycursor()
749       traduitV7V8.traduc(FichieraTraduire,FichierTraduit,log)
750       Pmw.hidebusycursor()
751       Entete="Fichier Traduit : "+FichierTraduit +"\n\n"
752       titre = "conversion de "+ FichieraTraduire
753
754       if  os.stat(log)[6] != 0L :
755           f=open(log)
756           texte_cr= f.read()
757           f.close()
758       else :
759           texte_cr = Entete  
760           commande="diff "+FichieraTraduire+" "+FichierTraduit+" >/dev/null"
761           try :
762             if os.system(commande) == 0 :
763                texte_cr = texte_cr + "Pas de difference entre le fichier V7 et le fichier traduit"
764           except :
765                pass
766
767       cptrendu = FenetreSurLigneWarning(self.appli,titre=titre,texte=texte_cr)
768