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
35 from jdcdisplay import JDCDISPLAY
36 from utils import extension,stripPath,save_in_file
37 from widgets import Fenetre,Ask_Format_Fichier
38 from fenetre_mc_inconnus import fenetre_mc_inconnus
45 ('Enregistrer','saveJDC'),
46 ('Enregistrer sous','saveasJDC'),
48 ('Fermer','closeJDC'),
49 ('Quitter','exitEFICAS'),
59 ('Rapport de validation','visuCRJDC'),
60 ('Fichier à plat','visu_a_plat'),
61 ('Fichier .py','visuJDC_py'),
62 ('Fichier source','visu_txt_brut_JDC'),
63 ('Paramètres Eficas','affichage_fichier_ini'),
64 ('Mots-clés inconnus','mc_inconnus'),
69 button_defs = (('New24',"newJDC","Création d'un nouveau fichier",'always'),
70 ('Open24',"openJDC","Ouverture d'un fichier existant",'always'),
71 ('Save24',"saveJDC","Sauvegarde du fichier courant",'always'),
72 ('Zoom24',"visuJDC","Visualisation du fichier de commandes",'always'),
74 ('Copy24',"copy","Copie l'objet courant",'jdc'),
75 ('Cut24',"cut","Coupe l'objet courant",'jdc'),
76 ('Paste24',"paste","Colle l'objet copié après l'objet courant",'jdc'),
78 ('Delete24',"delete","Supprime l'objet courant",'jdc'),
79 ('Help24',"view_doc","Documentation de l'objet courant",'jdc')
82 menu_defs=prefs.menu_defs['bureau']
86 button_defs=prefs.button_defs['bureau']
90 def __init__(self,appli,parent):
93 splash._splash.configure(text = "Création du bureau")
94 self.nb = Pmw.NoteBook(self.parent,raisecommand=self.selectJDC)
95 self.nb.pack(fill='both',expand=1)
96 self.JDCDisplay_courant=None
98 self.liste_JDCDisplay=[]
101 def cree_cataitem(self):
103 On récupère dans l'extension readercata les variables
104 qui servent par la suite pour la création des JDC
106 self.cataitem=self.appli.readercata.cataitem
107 self.cata=self.appli.readercata.cata
108 self.cata_ordonne_dico=self.appli.readercata.cata_ordonne_dico
109 self.code=self.appli.readercata.code
110 self.version_code=self.appli.readercata.version_code
111 self.fic_cata=self.appli.readercata.fic_cata
113 def selectJDC(self,event=None):
115 Cette méthode est appelée chaque fois que l'on sélectionne
116 l'onglet d'un JDC dans le NoteBook des JDC.
117 Elle permet de stocker dans les variable self.JDC et
118 self.JDCDisplay_courant les valeurs concernant le JDC courant
120 if len(self.liste_JDCDisplay) == 0 : return
121 #if self.JDCDisplay_courant : self.JDCDisplay_courant.jdc.unset_context()
122 numero_jdc = self.nb.index(self.nb.getcurselection())
123 self.JDCDisplay_courant = self.liste_JDCDisplay[numero_jdc]
124 self.JDC = self.JDCDisplay_courant.jdc
125 #self.JDC.set_context()
126 self.JDCName = self.JDC.nom
130 Initialise un nouveau JDC vierge
132 self.appli.statusbar.reset_affichage_infos()
134 CONTEXT.unset_current_step()
135 J=self.cata[0].JdC(cata=self.cata,
136 cata_ord_dico=self.cata_ordonne_dico,
140 self.ShowJDC(J,self.JDCName)
141 self.appli.toolbar.active_boutons()
143 def ShowJDC(self,JDC,nom,label_onglet=None):
145 Lance l'affichage du JDC cad création du JDCDisplay
146 Rajoute le JDCDisplay à la liste des JDCDisplay si label_onglet == None cad si on crée
147 bien un nouveau JDCDisplay et non si on remplace (renommage de l'onglet)
150 self.JDCName = self.JDC.nom = nom
151 #XXX CCAR: pour le moment mis en commentaire
152 #self.JDC.set_context()
153 if label_onglet == None :
154 label_onglet = self.GetLabelJDC()
155 self.nb.add(label_onglet,tab_text = nom,tab_width=20)
159 self.JDCDisplay_courant=JDCDISPLAY(self.JDC,nom,appli=self.appli,parent=self.nb.page(label_onglet))
161 self.liste_JDCDisplay.append(self.JDCDisplay_courant)
162 self.JDCDisplay_courant.modified='n'
163 self.JDCDisplay_courant.fichier=self.fileName
164 self.nb.selectpage(label_onglet)
165 self.nb.setnaturalsize()
166 texte = "Jeu de commandes :" + self.JDCName+" ouvert"
167 self.appli.affiche_infos(texte)
169 def closeJDC (self) :
171 Ferme le JDC courant et détruit l'onglet associé dans le notebook self.nb
173 if self.JDCDisplay_courant.modified == 'o' :
174 message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
175 reponse = askyesno(title="Sauvegarde du jdc courant",
178 test = self.saveJDC()
180 self.appli.affiche_infos("Sauvegarde impossible")
182 self.JDCDisplay_courant.jdc.supprime()
183 self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
184 self.nb.delete(self.nb.getcurselection())
185 #XXX CCAR: pour le moment mis en commentaire
186 #self.JDC.unset_context()
189 index = self.nb.index(self.nb.getcurselection())
190 self.JDCDisplay_courant = self.liste_JDCDisplay[index]
191 self.JDC = self.JDCDisplay_courant.jdc
193 self.JDCDisplay_courant = None
194 self.appli.toolbar.inactive_boutons()
197 return self.visuCR(mode='JDC')
199 def visuCR(self,mode):
201 Méthode permettant l'affichage du rapport de validation
204 if not hasattr(self,'JDC') : return
205 titre="rapport de validation du jeu de commandes courant"
206 cr = self.JDC.report()
208 from Noyau.N_CR import CR
210 cr.debut = "Début rapport de validation du catalogue"
211 cr.fin = "Fin rapport de validation du catalogue"
212 titre="rapport de validation du catalogue"
213 if hasattr(self,'cata_ordonne_cr') :
214 cr.add(self.cata_ordonne_cr)
215 if hasattr(self,'cata_dev_ordonne_cr') :
216 cr.add(self.cata_dev_ordonne_cr)
217 for cata in self.cata:
218 if hasattr(cata,'JdC'):
219 cr.add(cata.JdC.report())
221 self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
223 def openJDC(self,file=None):
225 Demande à l'utilisateur quel JDC existant il veut ouvrir
227 if self.code == 'ASTER':
228 filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),("Tous",'*'))
230 filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
231 if not hasattr(self,'initialdir'):
232 self.initialdir = self.appli.CONFIGURATION.rep_user
234 file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
235 defaultextension=".comm",
236 filetypes = filetypes,
237 initialdir = self.initialdir)
241 self.JDCName=stripPath(file)
242 self.initialdir = os.path.dirname(file)
245 #XXX CCAR: pour le moment mis en commentaire
246 #if self.JDCDisplay_courant:self.JDCDisplay_courant.jdc.unset_context()
248 format=self.appli.format_fichier.get()
249 # Il faut convertir le contenu du fichier en fonction du format
250 if convert.plugins.has_key(format):
251 # Le convertisseur existe on l'utilise
252 p=convert.plugins[format]()
254 text=p.convert('exec')
255 if not p.cr.estvide():
256 self.appli.affiche_infos("Erreur à la conversion")
258 titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
259 texte = str(p.cr)).wait()
262 # Il n'existe pas c'est une erreur
263 self.appli.affiche_infos("Type de fichier non reconnu")
264 showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
267 # On se met dans le repertoire ou se trouve le fichier de commandes
268 # pour trouver les eventuels fichiers include ou autres
269 # localises a cote du fichier de commandes
270 os.chdir(self.initialdir)
271 CONTEXT.unset_current_step()
272 J=self.cata[0].JdC(procedure=text,appli=self.appli,
273 cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
276 txt_exception = J.cr.get_mess_exception()
278 # des exceptions ont été levées à la création du JDC
279 # --> on affiche les erreurs mais pas le JDC
280 self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
281 showerror("Erreur fatale au chargement d'un fichier",txt_exception)
283 self.ShowJDC(J,self.JDCName)
284 self.appli.toolbar.active_boutons()
285 # si le JDC ne contient rien (vide), on retourne ici
286 if len(self.JDC.etapes) == 0 : return
287 # dans le cas où le JDC est invalide, on affiche son CR
288 cr = self.JDC.report()
289 if not cr.estvide() :
290 self.appli.top.update()
291 self.visuCR(mode='JDC')
294 def GetLabelJDC(self,nb_jdc = 'absent'):
296 Retourne le label de l'onglet du NoteBook associé au JDC à afficher
298 if nb_jdc == 'absent':
299 nb_jdc = len(self.nb.pagenames())
301 label_onglet = 'JDC'+`nb_jdc`
302 if label_onglet not in self.nb.pagenames() :
305 return self.GetLabelJDC(nb_jdc)
309 Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
310 donner le nom du fichier de sauvegarde
312 self.saveJDC(echo='oui')
314 def saveJDC(self,echo='non'):
316 Sauvegarde le JDC courant.
317 Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
318 Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il
320 Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
322 if not hasattr(self,'JDC') : return 0
323 format=self.appli.format_fichier.get()
324 if generator.plugins.has_key(format):
325 # Le generateur existe on l'utilise
326 g=generator.plugins[format]()
327 jdc_formate=g.gener(self.JDC,format='beautifie')
328 if not g.cr.estvide():
330 self.appli.affiche_infos("Erreur à la generation")
331 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
334 # Il n'existe pas c'est une erreur
335 self.appli.affiche_infos("Format %s non reconnu" % format)
336 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
338 self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
340 if echo =='oui' or self.JDCDisplay_courant.fichier == None:
341 return self.asknomsauvegardeJDC()
342 elif self.JDCDisplay_courant.fichier != None :
343 # le JDC a déjà un nom : on sauvegarde directement sans demander
344 # un autre nom au développeur
345 if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini) :
346 showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
349 self.JDCDisplay_courant.stop_modif()
350 self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
353 def asknomsauvegardeJDC(self):
354 """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
355 titre = "Sauvegarde d'un fichier de commandes "+self.code
356 if self.code == 'ASTER':
358 filtyp = ( ("ASTER", ".comm"),)
361 filtyp = ( (self.code, ".py"),)
362 sauvegarde = asksaveasfilename(title=titre,
363 defaultextension=defext,
365 initialdir = self.appli.CONFIGURATION.rep_user)
367 if not save_in_file(sauvegarde,self.jdc_fini) :
368 showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
371 self.JDCDisplay_courant.stop_modif()
372 self.appli.affiche_infos("Sauvegarde effectuée")
373 if sauvegarde != self.JDCDisplay_courant.fichier :
374 # l'utilisateur a sauvegardé le JDC sous un autre nom
375 self.JDCDisplay_courant.fichier = sauvegarde
376 self.JDCName = self.JDC.nom = stripPath(sauvegarde)
382 def changeNomPage(self):
383 """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
384 et recrée un autre onglet à la même place avec le bon nom
387 self.JDCDisplay_courant.jdc.nom = nom
388 nom_page = self.nb.getcurselection()
389 num_page = self.nb.index(nom_page)
390 tab = self.nb.tab(num_page)
391 tab.configure(text = nom)
393 def exitEFICAS(self):
395 Permet de sortir d'EFICAS en demandant à l'utilisateur
396 s'il veut sauvegarder les modifications en cours
398 liste = self.GetListeJDCaSauvegarder()
400 # Certains fichiers n'ont pas été sauvegardés ...
401 if askyesno("Enregistrer modifications","Enregister les modifications ?") :
402 test = self.saveall(liste)
405 if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
406 for JDCDisplay in self.liste_JDCDisplay:
407 JDCDisplay.jdc.supprime()
411 def GetListeJDCaSauvegarder(self) :
412 """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
413 if not self.JDCDisplay_courant : return []
414 if len(self.liste_JDCDisplay) == 0 : return l
416 for JDCDisplay in self.liste_JDCDisplay:
417 if JDCDisplay.modified == 'o' :
423 Lance la copie sur le JDC courant
425 if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
429 Lance le collage sur le JDC courant
431 if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
435 Lance le cut sur le JDC courant
437 if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
441 Lance la suppression du noeud courant
443 if not self.JDCDisplay_courant : return
445 if self.JDCDisplay_courant.modified == 'n' :
446 self.JDCDisplay_courant.init_modif()
447 pere = self.JDCDisplay_courant.node_selected.parent
448 self.JDCDisplay_courant.node_selected.delete()
450 except AttributeError:
453 def visuJDC_py(self):
455 Méthode permettant d'afficher dans une fenêtre à part l'écho au
456 format python du jdc courant
458 if not hasattr(self,'JDC') : return
459 jdc_fini = self.get_text_JDC('python')
460 if jdc_fini == None : return
462 titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
467 Méthode permettant d'afficher dans une fenêtre à part l'écho au
468 format .comm ou .py du jdc courant
470 if not hasattr(self,'JDC') : return
471 titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
472 format=self.appli.format_fichier.get()
473 self.jdc_fini = self.get_text_JDC(format)
474 if self.jdc_fini == None : return
475 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
477 def get_text_JDC(self,format):
478 if generator.plugins.has_key(format):
479 # Le generateur existe on l'utilise
480 g=generator.plugins[format]()
481 jdc_formate=g.gener(self.JDC,format='beautifie')
482 if not g.cr.estvide():
484 self.appli.affiche_infos("Erreur à la generation")
485 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
490 # Il n'existe pas c'est une erreur
491 self.appli.affiche_infos("Format %s non reconnu" % format)
492 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
497 Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
498 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
499 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
501 if not self.JDCDisplay_courant : return
503 cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
504 if cle_doc == None : return
505 cle_doc = string.replace(cle_doc,'.','')
506 cle_doc = string.replace(cle_doc,'-','')
507 commande = self.appli.CONFIGURATION.exec_acrobat
508 nom_fichier = cle_doc+".pdf"
509 rep_fichier = cle_doc[0:2]
510 fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
512 os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
513 elif os.name == 'posix':
514 script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
515 pid = os.system(script)
516 except AttributeError:
517 traceback.print_exc()
520 def visu_a_plat(self):
522 Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant
524 if not hasattr(self,'JDC') : return
525 titre = 'fichier '+ self.JDCName + ' à plat '
526 self.jdc_fini = self.get_text_JDC('aplat')
527 if self.jdc_fini == None : return
528 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
530 def visu_txt_brut_JDC(self):
532 Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
534 if not hasattr(self,'JDC') : return
535 titre = "fichier de commandes utilisateur"
536 #texte = self.JDC.procedure
538 if self.JDCDisplay_courant.fichier == None:
539 self.appli.affiche_infos("Pas de fichier initial")
540 showerror("Impossible de visualiser le fichier initial",
541 "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC")
543 f=open(self.JDCDisplay_courant.fichier,'r')
546 self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
548 def affichage_fichier_ini(self):
550 Affichage des valeurs des paramètres relus par Eficas
552 self.appli.CONFIGURATION.affichage_fichier_ini()
554 def saveall(self,liste):
556 Sauvegarde tous les JDC contenus dans liste
559 for JDCDisplay in liste :
560 self.JDC = JDCDisplay.jdc
561 test = test * self.saveJDC(echo = 'non')
565 # ---------------------------------------------------------------------------
566 # Méthodes liées aux mots-clés inconnus
567 # ---------------------------------------------------------------------------
569 def mc_inconnus(self):
570 l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
571 o = fenetre_mc_inconnus(l_mc)
572 l = o.wait_new_list()