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,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'extension 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
235 file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
236 defaultextension=".comm",
237 filetypes = filetypes,
238 initialdir = self.initialdir)
242 self.JDCName=stripPath(file)
243 self.initialdir = os.path.dirname(file)
246 #XXX CCAR: pour le moment mis en commentaire
247 #if self.JDCDisplay_courant:self.JDCDisplay_courant.jdc.unset_context()
249 format=self.appli.format_fichier.get()
250 # Il faut convertir le contenu du fichier en fonction du format
251 if convert.plugins.has_key(format):
252 # Le convertisseur existe on l'utilise
253 p=convert.plugins[format]()
255 text=p.convert('exec')
256 if not p.cr.estvide():
257 self.appli.affiche_infos("Erreur à la conversion")
259 titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
260 texte = str(p.cr)).wait()
263 # Il n'existe pas c'est une erreur
264 self.appli.affiche_infos("Type de fichier non reconnu")
265 showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
268 # On se met dans le repertoire ou se trouve le fichier de commandes
269 # pour trouver les eventuels fichiers include ou autres
270 # localises a cote du fichier de commandes
271 os.chdir(self.initialdir)
272 CONTEXT.unset_current_step()
273 J=self.cata[0].JdC(procedure=text,appli=self.appli,
274 cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
277 txt_exception = J.cr.get_mess_exception()
279 # des exceptions ont été levées à la création du JDC
280 # --> on affiche les erreurs mais pas le JDC
281 self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
282 showerror("Erreur fatale au chargement d'un fichier",txt_exception)
284 self.ShowJDC(J,self.JDCName)
285 self.appli.toolbar.active_boutons()
286 # si le JDC ne contient rien (vide), on retourne ici
287 if len(self.JDC.etapes) == 0 : return
288 # dans le cas où le JDC est invalide, on affiche son CR
289 cr = self.JDC.report()
290 if not cr.estvide() :
291 self.appli.top.update()
292 self.visuCR(mode='JDC')
295 def GetLabelJDC(self,nb_jdc = 'absent'):
297 Retourne le label de l'onglet du NoteBook associé au JDC à afficher
299 if nb_jdc == 'absent':
300 nb_jdc = len(self.nb.pagenames())
302 label_onglet = 'JDC'+`nb_jdc`
303 if label_onglet not in self.nb.pagenames() :
306 return self.GetLabelJDC(nb_jdc)
310 Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
311 donner le nom du fichier de sauvegarde
313 self.saveJDC(echo='oui')
315 def saveJDC(self,echo='non'):
317 Sauvegarde le JDC courant.
318 Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
319 Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il
321 Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
323 if not hasattr(self,'JDC') : return 0
324 format=self.appli.format_fichier.get()
325 if generator.plugins.has_key(format):
326 # Le generateur existe on l'utilise
327 g=generator.plugins[format]()
328 jdc_formate=g.gener(self.JDC,format='beautifie')
329 if not g.cr.estvide():
331 self.appli.affiche_infos("Erreur à la generation")
332 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
335 # Il n'existe pas c'est une erreur
336 self.appli.affiche_infos("Format %s non reconnu" % format)
337 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
339 self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
341 if echo =='oui' or self.JDCDisplay_courant.fichier == None:
342 return self.asknomsauvegardeJDC()
343 elif self.JDCDisplay_courant.fichier != None :
344 # le JDC a déjà un nom : on sauvegarde directement sans demander
345 # un autre nom au développeur
346 if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini) :
347 showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
350 self.JDCDisplay_courant.stop_modif()
351 self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
354 def asknomsauvegardeJDC(self):
355 """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
356 titre = "Sauvegarde d'un fichier de commandes "+self.code
357 if self.code == 'ASTER':
359 filtyp = ( ("ASTER", ".comm"),)
362 filtyp = ( (self.code, ".py"),)
363 sauvegarde = asksaveasfilename(title=titre,
364 defaultextension=defext,
366 initialdir = self.appli.CONFIGURATION.rep_user)
368 if not save_in_file(sauvegarde,self.jdc_fini) :
369 showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
372 self.JDCDisplay_courant.stop_modif()
373 self.appli.affiche_infos("Sauvegarde effectuée")
374 if sauvegarde != self.JDCDisplay_courant.fichier :
375 # l'utilisateur a sauvegardé le JDC sous un autre nom
376 self.JDCDisplay_courant.fichier = sauvegarde
377 self.JDCName = self.JDC.nom = stripPath(sauvegarde)
383 def changeNomPage(self):
384 """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
385 et recrée un autre onglet à la même place avec le bon nom
388 self.JDCDisplay_courant.jdc.nom = nom
389 nom_page = self.nb.getcurselection()
390 num_page = self.nb.index(nom_page)
391 tab = self.nb.tab(num_page)
392 tab.configure(text = nom)
394 def exitEFICAS(self):
396 Permet de sortir d'EFICAS en demandant à l'utilisateur
397 s'il veut sauvegarder les modifications en cours
399 liste = self.GetListeJDCaSauvegarder()
401 # Certains fichiers n'ont pas été sauvegardés ...
402 if askyesno("Enregistrer modifications","Enregister les modifications ?") :
403 test = self.saveall(liste)
406 if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
407 for JDCDisplay in self.liste_JDCDisplay:
408 JDCDisplay.jdc.supprime()
412 def GetListeJDCaSauvegarder(self) :
413 """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
414 if not self.JDCDisplay_courant : return []
415 if len(self.liste_JDCDisplay) == 0 : return l
417 for JDCDisplay in self.liste_JDCDisplay:
418 if JDCDisplay.modified == 'o' :
424 Lance la copie sur le JDC courant
426 if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
430 Lance le collage sur le JDC courant
432 if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
436 Lance le cut sur le JDC courant
438 if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
442 Lance la suppression du noeud courant
444 if not self.JDCDisplay_courant : return
446 if self.JDCDisplay_courant.modified == 'n' :
447 self.JDCDisplay_courant.init_modif()
448 pere = self.JDCDisplay_courant.node_selected.parent
449 self.JDCDisplay_courant.node_selected.delete()
451 except AttributeError:
454 def visuJDC_py(self):
456 Méthode permettant d'afficher dans une fenêtre à part l'écho au
457 format python du jdc courant
459 if not hasattr(self,'JDC') : return
460 jdc_fini = self.get_text_JDC('python')
461 if jdc_fini == None : return
463 titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
468 Méthode permettant d'afficher dans une fenêtre à part l'écho au
469 format .comm ou .py du jdc courant
471 if not hasattr(self,'JDC') : return
472 titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
473 format=self.appli.format_fichier.get()
474 self.jdc_fini = self.get_text_JDC(format)
475 if self.jdc_fini == None : return
476 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
478 def get_text_JDC(self,format):
479 if generator.plugins.has_key(format):
480 # Le generateur existe on l'utilise
481 g=generator.plugins[format]()
482 jdc_formate=g.gener(self.JDC,format='beautifie')
483 if not g.cr.estvide():
485 self.appli.affiche_infos("Erreur à la generation")
486 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
491 # Il n'existe pas c'est une erreur
492 self.appli.affiche_infos("Format %s non reconnu" % format)
493 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
498 Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
499 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
500 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
502 if not self.JDCDisplay_courant : return
504 cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
505 if cle_doc == None : return
506 cle_doc = string.replace(cle_doc,'.','')
507 cle_doc = string.replace(cle_doc,'-','')
508 commande = self.appli.CONFIGURATION.exec_acrobat
509 nom_fichier = cle_doc+".pdf"
510 rep_fichier = cle_doc[0:2]
511 fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
513 os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
514 elif os.name == 'posix':
515 script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
516 pid = os.system(script)
517 except AttributeError:
518 traceback.print_exc()
521 def visu_a_plat(self):
523 Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant
525 if not hasattr(self,'JDC') : return
526 titre = 'fichier '+ self.JDCName + ' à plat '
527 self.jdc_fini = self.get_text_JDC('aplat')
528 if self.jdc_fini == None : return
529 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
531 def visu_txt_brut_JDC(self):
533 Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
535 if not hasattr(self,'JDC') : return
536 titre = "fichier de commandes utilisateur"
537 #texte = self.JDC.procedure
539 if self.JDCDisplay_courant.fichier == None:
540 self.appli.affiche_infos("Pas de fichier initial")
541 showerror("Impossible de visualiser le fichier initial",
542 "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC")
544 f=open(self.JDCDisplay_courant.fichier,'r')
547 self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
549 def affichage_fichier_ini(self):
551 Affichage des valeurs des paramètres relus par Eficas
553 self.appli.CONFIGURATION.affichage_fichier_ini()
555 def saveall(self,liste):
557 Sauvegarde tous les JDC contenus dans liste
560 for JDCDisplay in liste :
561 self.JDC = JDCDisplay.jdc
562 test = test * self.saveJDC(echo = 'non')
566 # ---------------------------------------------------------------------------
567 # Méthodes liées aux mots-clés inconnus
568 # ---------------------------------------------------------------------------
570 def mc_inconnus(self):
571 l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
572 o = fenetre_mc_inconnus(l_mc)
573 l = o.wait_new_list()
574 #print "mc_inconnus_new_list: ",l
575 #CCAR: Il n' y a pas de retour vers le JDC
577 def aideEFICAS(self):
578 AIDE.go(master=self.parent)