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'),
69 ('Aide EFICAS','aideEFICAS'),
74 button_defs = (('New24',"newJDC","Création d'un nouveau fichier",'always'),
75 ('Open24',"openJDC","Ouverture d'un fichier existant",'always'),
76 ('Save24',"saveJDC","Sauvegarde du fichier courant",'always'),
77 ('Zoom24',"visuJDC","Visualisation du fichier de commandes",'always'),
79 ('Copy24',"copy","Copie l'objet courant",'jdc'),
80 ('Cut24',"cut","Coupe l'objet courant",'jdc'),
81 ('Paste24',"paste","Colle l'objet copié après l'objet courant",'jdc'),
83 ('Delete24',"delete","Supprime l'objet courant",'jdc'),
84 ('Help24',"view_doc","Documentation de l'objet courant",'jdc')
87 menu_defs=prefs.menu_defs['bureau']
91 button_defs=prefs.button_defs['bureau']
95 def __init__(self,appli,parent):
98 splash._splash.configure(text = "Création du bureau")
99 self.nb = Pmw.NoteBook(self.parent,raisecommand=self.selectJDC)
100 self.nb.pack(fill='both',expand=1)
101 self.JDCDisplay_courant=None
103 self.liste_JDCDisplay=[]
106 def cree_cataitem(self):
108 On récupère dans l'appli_composant readercata les variables
109 qui servent par la suite pour la création des JDC
111 self.cataitem=self.appli.readercata.cataitem
112 self.cata=self.appli.readercata.cata
113 self.cata_ordonne_dico=self.appli.readercata.cata_ordonne_dico
114 self.code=self.appli.readercata.code
115 self.version_code=self.appli.readercata.version_code
116 self.fic_cata=self.appli.readercata.fic_cata
118 def selectJDC(self,event=None):
120 Cette méthode est appelée chaque fois que l'on sélectionne
121 l'onglet d'un JDC dans le NoteBook des JDC.
122 Elle permet de stocker dans les variable self.JDC et
123 self.JDCDisplay_courant les valeurs concernant le JDC courant
125 if len(self.liste_JDCDisplay) == 0 : return
126 #if self.JDCDisplay_courant : self.JDCDisplay_courant.jdc.unset_context()
127 numero_jdc = self.nb.index(self.nb.getcurselection())
128 self.JDCDisplay_courant = self.liste_JDCDisplay[numero_jdc]
129 self.JDC = self.JDCDisplay_courant.jdc
130 #self.JDC.set_context()
131 self.JDCName = self.JDC.nom
135 Initialise un nouveau JDC vierge
137 self.appli.statusbar.reset_affichage_infos()
139 CONTEXT.unset_current_step()
140 J=self.cata[0].JdC(cata=self.cata,
141 cata_ord_dico=self.cata_ordonne_dico,
145 self.ShowJDC(J,self.JDCName)
146 self.appli.toolbar.active_boutons()
148 def ShowJDC(self,JDC,nom,label_onglet=None):
150 Lance l'affichage du JDC cad création du JDCDisplay
151 Rajoute le JDCDisplay à la liste des JDCDisplay si label_onglet == None cad si on crée
152 bien un nouveau JDCDisplay et non si on remplace (renommage de l'onglet)
155 self.JDCName = self.JDC.nom = nom
156 #XXX CCAR: pour le moment mis en commentaire
157 #self.JDC.set_context()
158 if label_onglet == None :
159 label_onglet = self.GetLabelJDC()
160 self.nb.add(label_onglet,tab_text = nom,tab_width=20)
164 self.JDCDisplay_courant=JDCDISPLAY(self.JDC,nom,appli=self.appli,parent=self.nb.page(label_onglet))
166 self.liste_JDCDisplay.append(self.JDCDisplay_courant)
167 self.JDCDisplay_courant.modified='n'
168 self.JDCDisplay_courant.fichier=self.fileName
169 self.nb.selectpage(label_onglet)
170 self.nb.setnaturalsize()
171 texte = "Jeu de commandes :" + self.JDCName+" ouvert"
172 self.appli.affiche_infos(texte)
174 def closeJDC (self) :
176 Ferme le JDC courant et détruit l'onglet associé dans le notebook self.nb
178 if self.JDCDisplay_courant.modified == 'o' :
179 message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
180 reponse = askyesno(title="Sauvegarde du jdc courant",
183 test = self.saveJDC()
185 self.appli.affiche_infos("Sauvegarde impossible")
187 self.JDCDisplay_courant.jdc.supprime()
188 self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
189 self.nb.delete(self.nb.getcurselection())
190 #XXX CCAR: pour le moment mis en commentaire
191 #self.JDC.unset_context()
194 index = self.nb.index(self.nb.getcurselection())
195 self.JDCDisplay_courant = self.liste_JDCDisplay[index]
196 self.JDC = self.JDCDisplay_courant.jdc
198 self.JDCDisplay_courant = None
199 self.appli.toolbar.inactive_boutons()
202 return self.visuCR(mode='JDC')
204 def visuCR(self,mode):
206 Méthode permettant l'affichage du rapport de validation
209 if not hasattr(self,'JDC') : return
210 titre="rapport de validation du jeu de commandes courant"
211 cr = self.JDC.report()
213 from Noyau.N_CR import CR
215 cr.debut = "Début rapport de validation du catalogue"
216 cr.fin = "Fin rapport de validation du catalogue"
217 titre="rapport de validation du catalogue"
218 if hasattr(self,'cata_ordonne_cr') :
219 cr.add(self.cata_ordonne_cr)
220 if hasattr(self,'cata_dev_ordonne_cr') :
221 cr.add(self.cata_dev_ordonne_cr)
222 for cata in self.cata:
223 if hasattr(cata,'JdC'):
224 cr.add(cata.JdC.report())
226 self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
228 def openJDC(self,file=None):
230 Demande à l'utilisateur quel JDC existant il veut ouvrir
232 if self.code == 'ASTER':
233 filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),("Tous",'*'))
235 filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
236 if not hasattr(self,'initialdir'):
237 #self.initialdir = self.appli.CONFIGURATION.rep_user
238 self.initialdir = self.appli.CONFIGURATION.initialdir
240 file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
241 defaultextension=".comm",
242 filetypes = filetypes,
243 initialdir = self.initialdir)
246 e=extension_fichier(file)
247 self.JDCName=stripPath(file)
248 self.initialdir = os.path.dirname(file)
251 #XXX CCAR: pour le moment mis en commentaire
252 #if self.JDCDisplay_courant:self.JDCDisplay_courant.jdc.unset_context()
254 format=self.appli.format_fichier.get()
255 # Il faut convertir le contenu du fichier en fonction du format
256 if convert.plugins.has_key(format):
257 # Le convertisseur existe on l'utilise
258 p=convert.plugins[format]()
260 text=p.convert('exec')
261 if not p.cr.estvide():
262 self.appli.affiche_infos("Erreur à la conversion")
264 titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
265 texte = str(p.cr)).wait()
268 # Il n'existe pas c'est une erreur
269 self.appli.affiche_infos("Type de fichier non reconnu")
270 showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
273 # On se met dans le repertoire ou se trouve le fichier de commandes
274 # pour trouver les eventuels fichiers include ou autres
275 # localises a cote du fichier de commandes
276 os.chdir(self.initialdir)
277 CONTEXT.unset_current_step()
278 J=self.cata[0].JdC(procedure=text,appli=self.appli,
279 cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
282 txt_exception = J.cr.get_mess_exception()
284 # des exceptions ont été levées à la création du JDC
285 # --> on affiche les erreurs mais pas le JDC
286 self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
287 showerror("Erreur fatale au chargement d'un fichier",txt_exception)
289 self.ShowJDC(J,self.JDCName)
290 self.appli.toolbar.active_boutons()
291 # si le JDC ne contient rien (vide), on retourne ici
292 if len(self.JDC.etapes) == 0 : return
293 # dans le cas où le JDC est invalide, on affiche son CR
294 cr = self.JDC.report()
295 if not cr.estvide() :
296 self.appli.top.update()
297 self.visuCR(mode='JDC')
300 def GetLabelJDC(self,nb_jdc = 'absent'):
302 Retourne le label de l'onglet du NoteBook associé au JDC à afficher
304 if nb_jdc == 'absent':
305 nb_jdc = len(self.nb.pagenames())
307 label_onglet = 'JDC'+`nb_jdc`
308 if label_onglet not in self.nb.pagenames() :
311 return self.GetLabelJDC(nb_jdc)
315 Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
316 donner le nom du fichier de sauvegarde
318 self.saveJDC(echo='oui')
320 def saveJDC(self,echo='non'):
322 Sauvegarde le JDC courant.
323 Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
324 Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il
326 Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
328 if not hasattr(self,'JDC') : return 0
329 format=self.appli.format_fichier.get()
330 if generator.plugins.has_key(format):
331 # Le generateur existe on l'utilise
332 g=generator.plugins[format]()
333 jdc_formate=g.gener(self.JDC,format='beautifie')
334 if not g.cr.estvide():
336 self.appli.affiche_infos("Erreur à la generation")
337 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
340 # Il n'existe pas c'est une erreur
341 self.appli.affiche_infos("Format %s non reconnu" % format)
342 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
344 self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
346 if echo =='oui' or self.JDCDisplay_courant.fichier == None:
347 return self.asknomsauvegardeJDC()
348 elif self.JDCDisplay_courant.fichier != None :
349 # le JDC a déjà un nom : on sauvegarde directement sans demander
350 # un autre nom au développeur
351 if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini) :
352 showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
355 self.JDCDisplay_courant.stop_modif()
356 self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
359 def asknomsauvegardeJDC(self):
360 """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
361 titre = "Sauvegarde d'un fichier de commandes "+self.code
362 if self.code == 'ASTER':
364 filtyp = ( ("ASTER", ".comm"),)
367 filtyp = ( (self.code, ".py"),)
368 sauvegarde = asksaveasfilename(title=titre,
369 defaultextension=defext,
371 initialdir = self.appli.CONFIGURATION.initialdir)
372 #initialdir = self.appli.CONFIGURATION.rep_user)
374 if not save_in_file(sauvegarde,self.jdc_fini) :
375 showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
378 self.JDCDisplay_courant.stop_modif()
379 self.appli.affiche_infos("Sauvegarde effectuée")
380 if sauvegarde != self.JDCDisplay_courant.fichier :
381 # l'utilisateur a sauvegardé le JDC sous un autre nom
382 self.JDCDisplay_courant.fichier = sauvegarde
383 self.JDCName = self.JDC.nom = stripPath(sauvegarde)
389 def changeNomPage(self):
390 """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
391 et recrée un autre onglet à la même place avec le bon nom
394 self.JDCDisplay_courant.jdc.nom = nom
395 nom_page = self.nb.getcurselection()
396 num_page = self.nb.index(nom_page)
397 tab = self.nb.tab(num_page)
398 tab.configure(text = nom)
400 def exitEFICAS(self):
402 Permet de sortir d'EFICAS en demandant à l'utilisateur
403 s'il veut sauvegarder les modifications en cours
405 liste = self.GetListeJDCaSauvegarder()
407 # Certains fichiers n'ont pas été sauvegardés ...
408 if askyesno("Enregistrer modifications","Enregister les modifications ?") :
409 test = self.saveall(liste)
412 if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
413 for JDCDisplay in self.liste_JDCDisplay:
414 JDCDisplay.jdc.supprime()
418 def GetListeJDCaSauvegarder(self) :
419 """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
420 if not self.JDCDisplay_courant : return []
421 if len(self.liste_JDCDisplay) == 0 : return l
423 for JDCDisplay in self.liste_JDCDisplay:
424 if JDCDisplay.modified == 'o' :
430 Lance la copie sur le JDC courant
432 if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
436 Lance le collage sur le JDC courant
438 if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
442 Lance le cut sur le JDC courant
444 if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
448 Lance la suppression du noeud courant
450 if not self.JDCDisplay_courant : return
452 if self.JDCDisplay_courant.modified == 'n' :
453 self.JDCDisplay_courant.init_modif()
454 pere = self.JDCDisplay_courant.node_selected.parent
455 self.JDCDisplay_courant.node_selected.delete()
457 except AttributeError:
460 def visuJDC_py(self):
462 Méthode permettant d'afficher dans une fenêtre à part l'écho au
463 format python du jdc courant
465 if not hasattr(self,'JDC') : return
466 jdc_fini = self.get_text_JDC('python')
467 if jdc_fini == None : return
469 titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
474 Méthode permettant d'afficher dans une fenêtre à part l'écho au
475 format .comm ou .py du jdc courant
477 if not hasattr(self,'JDC') : return
478 titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
479 format=self.appli.format_fichier.get()
480 self.jdc_fini = self.get_text_JDC(format)
481 if self.jdc_fini == None : return
482 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
484 def get_text_JDC(self,format):
485 if generator.plugins.has_key(format):
486 # Le generateur existe on l'utilise
487 g=generator.plugins[format]()
488 jdc_formate=g.gener(self.JDC,format='beautifie')
489 if not g.cr.estvide():
491 self.appli.affiche_infos("Erreur à la generation")
492 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
497 # Il n'existe pas c'est une erreur
498 self.appli.affiche_infos("Format %s non reconnu" % format)
499 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
504 Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
505 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
506 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
508 if not self.JDCDisplay_courant : return
510 cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
511 if cle_doc == None : return
512 cle_doc = string.replace(cle_doc,'.','')
513 cle_doc = string.replace(cle_doc,'-','')
514 commande = self.appli.CONFIGURATION.exec_acrobat
515 nom_fichier = cle_doc+".pdf"
516 rep_fichier = cle_doc[0:2]
517 fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
519 os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
520 elif os.name == 'posix':
521 script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
522 pid = os.system(script)
523 except AttributeError:
524 traceback.print_exc()
527 def visu_a_plat(self):
529 Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant
531 if not hasattr(self,'JDC') : return
532 titre = 'fichier '+ self.JDCName + ' à plat '
533 self.jdc_fini = self.get_text_JDC('aplat')
534 if self.jdc_fini == None : return
535 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
537 def visu_txt_brut_JDC(self):
539 Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
541 if not hasattr(self,'JDC') : return
542 titre = "fichier de commandes utilisateur"
543 #texte = self.JDC.procedure
545 if self.JDCDisplay_courant.fichier == None:
546 self.appli.affiche_infos("Pas de fichier initial")
547 showerror("Impossible de visualiser le fichier initial",
548 "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC")
550 f=open(self.JDCDisplay_courant.fichier,'r')
553 self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
555 def affichage_fichier_ini(self):
557 Affichage des valeurs des paramètres relus par Eficas
559 self.appli.CONFIGURATION.affichage_fichier_ini()
561 def saveall(self,liste):
563 Sauvegarde tous les JDC contenus dans liste
566 for JDCDisplay in liste :
567 self.JDC = JDCDisplay.jdc
568 test = test * self.saveJDC(echo = 'non')
572 # ---------------------------------------------------------------------------
573 # Méthodes liées aux mots-clés inconnus
574 # ---------------------------------------------------------------------------
576 def mc_inconnus(self):
577 l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
578 o = fenetre_mc_inconnus(l_mc)
579 l = o.wait_new_list()
580 #print "mc_inconnus_new_list: ",l
581 #CCAR: Il n' y a pas de retour vers le JDC
583 def aideEFICAS(self):
584 AIDE.go(master=self.parent)