1 # CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
21 Ce module contient la classe BUREAU qui gere les JDC ouverts
27 from tkFileDialog import askopenfilename,asksaveasfilename
28 from tkMessageBox import showinfo,askyesno,showerror
36 from jdcdisplay import JDCDISPLAY
37 from utils import extension_fichier,stripPath,save_in_file
38 from widgets import Fenetre,Ask_Format_Fichier
39 from fenetre_mc_inconnus import fenetre_mc_inconnus
46 ('Enregistrer','saveJDC'),
47 ('Enregistrer sous','saveasJDC'),
49 ('Fermer','closeJDC'),
50 ('Quitter','exitEFICAS'),
60 ('Rapport de validation','visuCRJDC'),
61 ('Fichier à plat','visu_a_plat'),
62 ('Fichier .py','visuJDC_py'),
63 ('Fichier source','visu_txt_brut_JDC'),
64 ('Paramètres Eficas','affichage_fichier_ini'),
65 ('Mots-clés inconnus','mc_inconnus'),
70 button_defs = (('New24',"newJDC","Création d'un nouveau fichier",'always'),
71 ('Open24',"openJDC","Ouverture d'un fichier existant",'always'),
72 ('Save24',"saveJDC","Sauvegarde du fichier courant",'always'),
73 ('Zoom24',"visuJDC","Visualisation du fichier de commandes",'always'),
75 ('Copy24',"copy","Copie l'objet courant",'jdc'),
76 ('Cut24',"cut","Coupe l'objet courant",'jdc'),
77 ('Paste24',"paste","Colle l'objet copié après l'objet courant",'jdc'),
79 ('Delete24',"delete","Supprime l'objet courant",'jdc'),
80 ('Help24',"view_doc","Documentation de l'objet courant",'jdc')
83 menu_defs=prefs.menu_defs['bureau']
87 button_defs=prefs.button_defs['bureau']
91 def __init__(self,appli,parent):
94 splash._splash.configure(text = "Création du bureau")
95 self.nb = Pmw.NoteBook(self.parent,raisecommand=self.selectJDC)
96 self.nb.pack(fill='both',expand=1)
97 self.JDCDisplay_courant=None
99 self.liste_JDCDisplay=[]
102 def cree_cataitem(self):
104 On récupère dans l'appli_composant readercata les variables
105 qui servent par la suite pour la création des JDC
107 self.cataitem=self.appli.readercata.cataitem
108 self.cata=self.appli.readercata.cata
109 self.cata_ordonne_dico=self.appli.readercata.cata_ordonne_dico
110 self.code=self.appli.readercata.code
111 self.version_code=self.appli.readercata.version_code
112 self.fic_cata=self.appli.readercata.fic_cata
114 def selectJDC(self,event=None):
116 Cette méthode est appelée chaque fois que l'on sélectionne
117 l'onglet d'un JDC dans le NoteBook des JDC.
118 Elle permet de stocker dans les variable self.JDC et
119 self.JDCDisplay_courant les valeurs concernant le JDC courant
121 if len(self.liste_JDCDisplay) == 0 : return
122 #if self.JDCDisplay_courant : self.JDCDisplay_courant.jdc.unset_context()
123 numero_jdc = self.nb.index(self.nb.getcurselection())
124 self.JDCDisplay_courant = self.liste_JDCDisplay[numero_jdc]
125 self.JDC = self.JDCDisplay_courant.jdc
126 #self.JDC.set_context()
127 self.JDCName = self.JDC.nom
131 Initialise un nouveau JDC vierge
133 self.appli.statusbar.reset_affichage_infos()
135 CONTEXT.unset_current_step()
136 J=self.cata[0].JdC(cata=self.cata,
137 cata_ord_dico=self.cata_ordonne_dico,
141 self.ShowJDC(J,self.JDCName)
142 self.appli.toolbar.active_boutons()
144 def ShowJDC(self,JDC,nom,label_onglet=None):
146 Lance l'affichage du JDC cad création du JDCDisplay
147 Rajoute le JDCDisplay à la liste des JDCDisplay si label_onglet == None cad si on crée
148 bien un nouveau JDCDisplay et non si on remplace (renommage de l'onglet)
151 self.JDCName = self.JDC.nom = nom
152 #XXX CCAR: pour le moment mis en commentaire
153 #self.JDC.set_context()
154 if label_onglet == None :
155 label_onglet = self.GetLabelJDC()
156 self.nb.add(label_onglet,tab_text = nom,tab_width=20)
160 self.JDCDisplay_courant=JDCDISPLAY(self.JDC,nom,appli=self.appli,parent=self.nb.page(label_onglet))
162 self.liste_JDCDisplay.append(self.JDCDisplay_courant)
163 self.JDCDisplay_courant.modified='n'
164 self.JDCDisplay_courant.fichier=self.fileName
165 self.nb.selectpage(label_onglet)
166 self.nb.setnaturalsize()
167 texte = "Jeu de commandes :" + self.JDCName+" ouvert"
168 self.appli.affiche_infos(texte)
170 def closeJDC (self) :
172 Ferme le JDC courant et détruit l'onglet associé dans le notebook self.nb
174 if self.JDCDisplay_courant.modified == 'o' :
175 message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
176 reponse = askyesno(title="Sauvegarde du jdc courant",
179 test = self.saveJDC()
181 self.appli.affiche_infos("Sauvegarde impossible")
183 self.JDCDisplay_courant.jdc.supprime()
184 self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
185 self.nb.delete(self.nb.getcurselection())
186 #XXX CCAR: pour le moment mis en commentaire
187 #self.JDC.unset_context()
190 index = self.nb.index(self.nb.getcurselection())
191 self.JDCDisplay_courant = self.liste_JDCDisplay[index]
192 self.JDC = self.JDCDisplay_courant.jdc
194 self.JDCDisplay_courant = None
195 self.appli.toolbar.inactive_boutons()
198 return self.visuCR(mode='JDC')
200 def visuCR(self,mode):
202 Méthode permettant l'affichage du rapport de validation
205 if not hasattr(self,'JDC') : return
206 titre="rapport de validation du jeu de commandes courant"
207 cr = self.JDC.report()
209 from Noyau.N_CR import CR
211 cr.debut = "Début rapport de validation du catalogue"
212 cr.fin = "Fin rapport de validation du catalogue"
213 titre="rapport de validation du catalogue"
214 if hasattr(self,'cata_ordonne_cr') :
215 cr.add(self.cata_ordonne_cr)
216 if hasattr(self,'cata_dev_ordonne_cr') :
217 cr.add(self.cata_dev_ordonne_cr)
218 for cata in self.cata:
219 if hasattr(cata,'JdC'):
220 cr.add(cata.JdC.report())
222 self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
224 def openJDC(self,file=None):
226 Demande à l'utilisateur quel JDC existant il veut ouvrir
228 if self.code == 'ASTER':
229 filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),("Tous",'*'))
231 filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
232 if not hasattr(self,'initialdir'):
233 #self.initialdir = self.appli.CONFIGURATION.rep_user
234 self.initialdir = self.appli.CONFIGURATION.initialdir
236 file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
237 defaultextension=".comm",
238 filetypes = filetypes,
239 initialdir = self.initialdir)
242 e=extension_fichier(file)
243 self.JDCName=stripPath(file)
244 self.initialdir = os.path.dirname(file)
247 #XXX CCAR: pour le moment mis en commentaire
248 #if self.JDCDisplay_courant:self.JDCDisplay_courant.jdc.unset_context()
250 format=self.appli.format_fichier.get()
251 # Il faut convertir le contenu du fichier en fonction du format
252 if convert.plugins.has_key(format):
253 # Le convertisseur existe on l'utilise
254 p=convert.plugins[format]()
256 text=p.convert('exec')
257 if not p.cr.estvide():
258 self.appli.affiche_infos("Erreur à la conversion")
260 titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
261 texte = str(p.cr)).wait()
264 # Il n'existe pas c'est une erreur
265 self.appli.affiche_infos("Type de fichier non reconnu")
266 showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
269 # On se met dans le repertoire ou se trouve le fichier de commandes
270 # pour trouver les eventuels fichiers include ou autres
271 # localises a cote du fichier de commandes
272 os.chdir(self.initialdir)
273 CONTEXT.unset_current_step()
274 J=self.cata[0].JdC(procedure=text,appli=self.appli,
275 cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
278 txt_exception = J.cr.get_mess_exception()
280 # des exceptions ont été levées à la création du JDC
281 # --> on affiche les erreurs mais pas le JDC
282 self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
283 showerror("Erreur fatale au chargement d'un fichier",txt_exception)
285 self.ShowJDC(J,self.JDCName)
286 self.appli.toolbar.active_boutons()
287 # si le JDC ne contient rien (vide), on retourne ici
288 if len(self.JDC.etapes) == 0 : return
289 # dans le cas où le JDC est invalide, on affiche son CR
290 cr = self.JDC.report()
291 if not cr.estvide() :
292 self.appli.top.update()
293 self.visuCR(mode='JDC')
296 def GetLabelJDC(self,nb_jdc = 'absent'):
298 Retourne le label de l'onglet du NoteBook associé au JDC à afficher
300 if nb_jdc == 'absent':
301 nb_jdc = len(self.nb.pagenames())
303 label_onglet = 'JDC'+`nb_jdc`
304 if label_onglet not in self.nb.pagenames() :
307 return self.GetLabelJDC(nb_jdc)
311 Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
312 donner le nom du fichier de sauvegarde
314 self.saveJDC(echo='oui')
316 def saveJDC(self,echo='non'):
318 Sauvegarde le JDC courant.
319 Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
320 Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il
322 Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
324 if not hasattr(self,'JDC') : return 0
325 format=self.appli.format_fichier.get()
326 if generator.plugins.has_key(format):
327 # Le generateur existe on l'utilise
328 g=generator.plugins[format]()
329 jdc_formate=g.gener(self.JDC,format='beautifie')
330 if not g.cr.estvide():
332 self.appli.affiche_infos("Erreur à la generation")
333 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
336 # Il n'existe pas c'est une erreur
337 self.appli.affiche_infos("Format %s non reconnu" % format)
338 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
340 self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
342 if echo =='oui' or self.JDCDisplay_courant.fichier == None:
343 return self.asknomsauvegardeJDC()
344 elif self.JDCDisplay_courant.fichier != None :
345 # le JDC a déjà un nom : on sauvegarde directement sans demander
346 # un autre nom au développeur
347 if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini) :
348 showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
351 self.JDCDisplay_courant.stop_modif()
352 self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
355 def asknomsauvegardeJDC(self):
356 """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
357 titre = "Sauvegarde d'un fichier de commandes "+self.code
358 if self.code == 'ASTER':
360 filtyp = ( ("ASTER", ".comm"),)
363 filtyp = ( (self.code, ".py"),)
364 sauvegarde = asksaveasfilename(title=titre,
365 defaultextension=defext,
367 initialdir = self.appli.CONFIGURATION.initialdir)
368 #initialdir = self.appli.CONFIGURATION.rep_user)
370 if not save_in_file(sauvegarde,self.jdc_fini) :
371 showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
374 self.JDCDisplay_courant.stop_modif()
375 self.appli.affiche_infos("Sauvegarde effectuée")
376 if sauvegarde != self.JDCDisplay_courant.fichier :
377 # l'utilisateur a sauvegardé le JDC sous un autre nom
378 self.JDCDisplay_courant.fichier = sauvegarde
379 self.JDCName = self.JDC.nom = stripPath(sauvegarde)
385 def changeNomPage(self):
386 """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
387 et recrée un autre onglet à la même place avec le bon nom
390 self.JDCDisplay_courant.jdc.nom = nom
391 nom_page = self.nb.getcurselection()
392 num_page = self.nb.index(nom_page)
393 tab = self.nb.tab(num_page)
394 tab.configure(text = nom)
396 def exitEFICAS(self):
398 Permet de sortir d'EFICAS en demandant à l'utilisateur
399 s'il veut sauvegarder les modifications en cours
401 liste = self.GetListeJDCaSauvegarder()
403 # Certains fichiers n'ont pas été sauvegardés ...
404 if askyesno("Enregistrer modifications","Enregister les modifications ?") :
405 test = self.saveall(liste)
408 if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
409 for JDCDisplay in self.liste_JDCDisplay:
410 JDCDisplay.jdc.supprime()
414 def GetListeJDCaSauvegarder(self) :
415 """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
416 if not self.JDCDisplay_courant : return []
417 if len(self.liste_JDCDisplay) == 0 : return l
419 for JDCDisplay in self.liste_JDCDisplay:
420 if JDCDisplay.modified == 'o' :
426 Lance la copie sur le JDC courant
428 if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
432 Lance le collage sur le JDC courant
434 if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
438 Lance le cut sur le JDC courant
440 if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
444 Lance la suppression du noeud courant
446 if not self.JDCDisplay_courant : return
448 if self.JDCDisplay_courant.modified == 'n' :
449 self.JDCDisplay_courant.init_modif()
450 pere = self.JDCDisplay_courant.node_selected.parent
451 self.JDCDisplay_courant.node_selected.delete()
453 except AttributeError:
456 def visuJDC_py(self):
458 Méthode permettant d'afficher dans une fenêtre à part l'écho au
459 format python du jdc courant
461 if not hasattr(self,'JDC') : return
462 jdc_fini = self.get_text_JDC('python')
463 if jdc_fini == None : return
465 titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
470 Méthode permettant d'afficher dans une fenêtre à part l'écho au
471 format .comm ou .py du jdc courant
473 if not hasattr(self,'JDC') : return
474 titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
475 format=self.appli.format_fichier.get()
476 self.jdc_fini = self.get_text_JDC(format)
477 if self.jdc_fini == None : return
478 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
480 def get_text_JDC(self,format):
481 if generator.plugins.has_key(format):
482 # Le generateur existe on l'utilise
483 g=generator.plugins[format]()
484 jdc_formate=g.gener(self.JDC,format='beautifie')
485 if not g.cr.estvide():
487 self.appli.affiche_infos("Erreur à la generation")
488 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
493 # Il n'existe pas c'est une erreur
494 self.appli.affiche_infos("Format %s non reconnu" % format)
495 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
500 Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
501 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
502 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
504 if not self.JDCDisplay_courant : return
506 cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
507 if cle_doc == None : return
508 cle_doc = string.replace(cle_doc,'.','')
509 cle_doc = string.replace(cle_doc,'-','')
510 commande = self.appli.CONFIGURATION.exec_acrobat
511 nom_fichier = cle_doc+".pdf"
512 rep_fichier = cle_doc[0:2]
513 fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
515 os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
516 elif os.name == 'posix':
517 script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
518 pid = os.system(script)
519 except AttributeError:
520 traceback.print_exc()
523 def visu_a_plat(self):
525 Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant
527 if not hasattr(self,'JDC') : return
528 titre = 'fichier '+ self.JDCName + ' à plat '
529 self.jdc_fini = self.get_text_JDC('aplat')
530 if self.jdc_fini == None : return
531 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
533 def visu_txt_brut_JDC(self):
535 Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
537 if not hasattr(self,'JDC') : return
538 titre = "fichier de commandes utilisateur"
539 #texte = self.JDC.procedure
541 if self.JDCDisplay_courant.fichier == None:
542 self.appli.affiche_infos("Pas de fichier initial")
543 showerror("Impossible de visualiser le fichier initial",
544 "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC")
546 f=open(self.JDCDisplay_courant.fichier,'r')
549 self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
551 def affichage_fichier_ini(self):
553 Affichage des valeurs des paramètres relus par Eficas
555 self.appli.CONFIGURATION.affichage_fichier_ini()
557 def saveall(self,liste):
559 Sauvegarde tous les JDC contenus dans liste
562 for JDCDisplay in liste :
563 self.JDC = JDCDisplay.jdc
564 test = test * self.saveJDC(echo = 'non')
568 # ---------------------------------------------------------------------------
569 # Méthodes liées aux mots-clés inconnus
570 # ---------------------------------------------------------------------------
572 def mc_inconnus(self):
573 l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
574 o = fenetre_mc_inconnus(l_mc)
575 l = o.wait_new_list()
576 #print "mc_inconnus_new_list: ",l
577 #CCAR: Il n' y a pas de retour vers le JDC
579 def aideEFICAS(self):
580 AIDE.go(master=self.parent)