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 widgets import askopenfilename,asksaveasfilename
28 from widgets 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,
143 rep_mat=self.appli.CONFIGURATION.rep_mat,
147 self.ShowJDC(J,self.JDCName)
148 self.appli.toolbar.active_boutons()
150 def ShowJDC(self,JDC,nom,label_onglet=None):
152 Lance l'affichage du JDC cad création du JDCDisplay
153 Rajoute le JDCDisplay à la liste des JDCDisplay si label_onglet == None cad si on crée
154 bien un nouveau JDCDisplay et non si on remplace (renommage de l'onglet)
157 self.JDCName = self.JDC.nom = nom
158 #XXX CCAR: pour le moment mis en commentaire
159 #self.JDC.set_context()
160 if label_onglet == None :
161 label_onglet = self.GetLabelJDC()
162 self.nb.add(label_onglet,tab_text = nom,tab_width=20)
166 self.JDCDisplay_courant=JDCDISPLAY(self.JDC,nom,appli=self.appli,parent=self.nb.page(label_onglet))
168 self.liste_JDCDisplay.append(self.JDCDisplay_courant)
169 self.JDCDisplay_courant.modified='n'
170 self.JDCDisplay_courant.fichier=self.fileName
171 self.nb.selectpage(label_onglet)
172 self.nb.setnaturalsize()
173 texte = "Jeu de commandes :" + self.JDCName+" ouvert"
174 self.appli.affiche_infos(texte)
176 def closeJDC (self) :
178 Ferme le JDC courant et détruit l'onglet associé dans le notebook self.nb
180 if self.JDCDisplay_courant.modified == 'o' :
181 message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
182 reponse = askyesno(title="Sauvegarde du jdc courant",
185 test = self.saveJDC()
187 self.appli.affiche_infos("Sauvegarde impossible")
189 self.JDCDisplay_courant.jdc.supprime()
190 self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
191 self.nb.delete(self.nb.getcurselection())
192 #XXX CCAR: pour le moment mis en commentaire
193 #self.JDC.unset_context()
196 index = self.nb.index(self.nb.getcurselection())
197 self.JDCDisplay_courant = self.liste_JDCDisplay[index]
198 self.JDC = self.JDCDisplay_courant.jdc
200 self.JDCDisplay_courant = None
201 self.appli.toolbar.inactive_boutons()
204 return self.visuCR(mode='JDC')
206 def visuCR(self,mode):
208 Méthode permettant l'affichage du rapport de validation
211 if not hasattr(self,'JDC') : return
212 titre="rapport de validation du jeu de commandes courant"
213 cr = self.JDC.report()
214 self.update_jdc_courant()
216 from Noyau.N_CR import CR
218 cr.debut = "Début rapport de validation du catalogue"
219 cr.fin = "Fin rapport de validation du catalogue"
220 titre="rapport de validation du catalogue"
221 if hasattr(self,'cata_ordonne_cr') :
222 cr.add(self.cata_ordonne_cr)
223 if hasattr(self,'cata_dev_ordonne_cr') :
224 cr.add(self.cata_dev_ordonne_cr)
225 for cata in self.cata:
226 if hasattr(cata,'JdC'):
227 cr.add(cata.JdC.report())
229 self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
231 def openJDC(self,file=None):
233 Demande à l'utilisateur quel JDC existant il veut ouvrir
235 if self.code == 'ASTER':
236 filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),("Tous",'*'))
238 filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
239 if not hasattr(self,'initialdir'):
240 #self.initialdir = self.appli.CONFIGURATION.rep_user
241 self.initialdir = self.appli.CONFIGURATION.initialdir
243 file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
244 defaultextension=".comm",
245 filetypes = filetypes,
246 initialdir = self.initialdir)
249 e=extension_fichier(file)
250 self.JDCName=stripPath(file)
251 self.initialdir = os.path.dirname(file)
254 #XXX CCAR: pour le moment mis en commentaire
255 #if self.JDCDisplay_courant:self.JDCDisplay_courant.jdc.unset_context()
257 format=self.appli.format_fichier.get()
258 # Il faut convertir le contenu du fichier en fonction du format
259 if convert.plugins.has_key(format):
260 # Le convertisseur existe on l'utilise
261 p=convert.plugins[format]()
263 text=p.convert('exec')
264 if not p.cr.estvide():
265 self.appli.affiche_infos("Erreur à la conversion")
267 titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
268 texte = str(p.cr)).wait()
271 # Il n'existe pas c'est une erreur
272 self.appli.affiche_infos("Type de fichier non reconnu")
273 showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
276 # On se met dans le repertoire ou se trouve le fichier de commandes
277 # pour trouver les eventuels fichiers include ou autres
278 # localises a cote du fichier de commandes
279 os.chdir(self.initialdir)
280 CONTEXT.unset_current_step()
281 J=self.cata[0].JdC(procedure=text,appli=self.appli,
282 cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
284 rep_mat=self.appli.CONFIGURATION.rep_mat,
287 txt_exception = J.cr.get_mess_exception()
289 # des exceptions ont été levées à la création du JDC
290 # --> on affiche les erreurs mais pas le JDC
291 self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
292 showerror("Erreur fatale au chargement d'un fichier",txt_exception)
294 self.ShowJDC(J,self.JDCName)
295 self.appli.toolbar.active_boutons()
296 # si le JDC ne contient rien (vide), on retourne ici
297 if len(self.JDC.etapes) == 0 : return
298 # dans le cas où le JDC est invalide, on affiche son CR
299 if not self.JDC.isvalid():
300 #cr = self.JDC.report()
301 #if not cr.estvide() :
302 self.appli.top.update()
303 self.visuCR(mode='JDC')
306 def GetLabelJDC(self,nb_jdc = 'absent'):
308 Retourne le label de l'onglet du NoteBook associé au JDC à afficher
310 if nb_jdc == 'absent':
311 nb_jdc = len(self.nb.pagenames())
313 label_onglet = 'JDC'+`nb_jdc`
314 if label_onglet not in self.nb.pagenames() :
317 return self.GetLabelJDC(nb_jdc)
321 Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
322 donner le nom du fichier de sauvegarde
324 self.saveJDC(echo='oui')
326 def saveJDC(self,echo='non'):
328 Sauvegarde le JDC courant.
329 Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
330 Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il
332 Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
334 if not hasattr(self,'JDC') : return 0
335 format=self.appli.format_fichier.get()
336 if generator.plugins.has_key(format):
337 # Le generateur existe on l'utilise
338 g=generator.plugins[format]()
339 jdc_formate=g.gener(self.JDC,format='beautifie')
340 if not g.cr.estvide():
342 self.appli.affiche_infos("Erreur à la generation")
343 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
346 # Il n'existe pas c'est une erreur
347 self.appli.affiche_infos("Format %s non reconnu" % format)
348 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
350 self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
352 if echo =='oui' or self.JDCDisplay_courant.fichier == None:
353 return self.asknomsauvegardeJDC()
354 elif self.JDCDisplay_courant.fichier != None :
356 # Pour sauvegarde dans l etude si lancement depuis salome
357 if self.appli.salome != 0:
359 self.appli.salome.rangeInStudy(self.JDCDisplay_courant.fichier)
360 from panelsSalome import SALOME_UNIQUE_BASE_Panel
361 if len(SALOME_UNIQUE_BASE_Panel.dict_fichier_unite) > 0 :
362 self.appli.salome.creeConfigTxt(self.appli.CONFIGURATION.initialdir,SALOME_UNIQUE_BASE_Panel.dict_fichier_unite)
363 #PN Fin Ajout --> Salome
364 # le JDC a déjà un nom : on sauvegarde directement sans demander
365 # un autre nom au développeur
366 if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini) :
367 showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
370 self.JDCDisplay_courant.stop_modif()
371 self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
374 def asknomsauvegardeJDC(self):
375 """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
376 titre = "Sauvegarde d'un fichier de commandes "+self.code
377 if self.code == 'ASTER':
379 filtyp = ( ("ASTER", ".comm"),)
382 filtyp = ( (self.code, ".py"),)
383 sauvegarde = asksaveasfilename(title=titre,
384 defaultextension=defext,
386 initialdir = self.appli.CONFIGURATION.initialdir)
387 #initialdir = self.appli.CONFIGURATION.rep_user)
389 # PN ajout --> Salome
390 # Pour sauvegarde dans l etude si lancement depuis salome
391 if self.appli.salome != 0:
393 self.appli.salome.rangeInStudy(sauvegarde)
394 from panelsSalome import SALOME_UNIQUE_BASE_Panel
395 if len(SALOME_UNIQUE_BASE_Panel.dict_fichier_unite) > 0 :
396 self.appli.salome.creeConfigTxt(self.appli.CONFIGURATION.initialdir,SALOME_UNIQUE_BASE_Panel.dict_fichier_unite)
397 # PN fin ajout --> Salome
398 if not save_in_file(sauvegarde,self.jdc_fini) :
399 showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
402 self.JDCDisplay_courant.stop_modif()
403 self.appli.affiche_infos("Sauvegarde effectuée")
404 if sauvegarde != self.JDCDisplay_courant.fichier :
405 # l'utilisateur a sauvegardé le JDC sous un autre nom
406 self.JDCDisplay_courant.fichier = sauvegarde
407 self.JDCName = self.JDC.nom = stripPath(sauvegarde)
413 def changeNomPage(self):
414 """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
415 et recrée un autre onglet à la même place avec le bon nom
418 self.JDCDisplay_courant.jdc.nom = nom
419 nom_page = self.nb.getcurselection()
420 num_page = self.nb.index(nom_page)
421 tab = self.nb.tab(num_page)
422 tab.configure(text = nom)
424 def exitEFICAS(self):
426 Permet de sortir d'EFICAS en demandant à l'utilisateur
427 s'il veut sauvegarder les modifications en cours
429 liste = self.GetListeJDCaSauvegarder()
431 # Certains fichiers n'ont pas été sauvegardés ...
432 if askyesno("Enregistrer modifications","Enregister les modifications ?") :
433 test = self.saveall(liste)
436 if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
437 for JDCDisplay in self.liste_JDCDisplay:
438 JDCDisplay.jdc.supprime()
442 def GetListeJDCaSauvegarder(self) :
443 """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
444 if not self.JDCDisplay_courant : return []
445 if len(self.liste_JDCDisplay) == 0 : return l
447 for JDCDisplay in self.liste_JDCDisplay:
448 if JDCDisplay.modified == 'o' :
454 Lance la copie sur le JDC courant
456 if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
460 Lance le collage sur le JDC courant
462 if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
466 Lance le cut sur le JDC courant
468 if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
472 Lance la suppression du noeud courant
474 if not self.JDCDisplay_courant : return
476 if self.JDCDisplay_courant.modified == 'n' :
477 self.JDCDisplay_courant.init_modif()
478 pere = self.JDCDisplay_courant.node_selected.parent
479 self.JDCDisplay_courant.node_selected.delete()
481 except AttributeError:
484 def visuJDC_py(self):
486 Méthode permettant d'afficher dans une fenêtre à part l'écho au
487 format python du jdc courant
489 if not hasattr(self,'JDC') : return
490 jdc_fini = self.get_text_JDC('python')
491 if jdc_fini == None : return
493 titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
498 Méthode permettant d'afficher dans une fenêtre à part l'écho au
499 format .comm ou .py du jdc courant
501 if not hasattr(self,'JDC') : return
502 titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
503 format=self.appli.format_fichier.get()
504 self.jdc_fini = self.get_text_JDC(format)
505 if self.jdc_fini == None : return
506 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
508 def get_text_JDC(self,format):
509 if generator.plugins.has_key(format):
510 # Le generateur existe on l'utilise
511 g=generator.plugins[format]()
512 jdc_formate=g.gener(self.JDC,format='beautifie')
513 if not g.cr.estvide():
515 self.appli.affiche_infos("Erreur à la generation")
516 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
521 # Il n'existe pas c'est une erreur
522 self.appli.affiche_infos("Format %s non reconnu" % format)
523 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
528 Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
529 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
530 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
532 if not self.JDCDisplay_courant : return
534 cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
535 if cle_doc == None : return
536 cle_doc = string.replace(cle_doc,'.','')
537 cle_doc = string.replace(cle_doc,'-','')
538 commande = self.appli.CONFIGURATION.exec_acrobat
539 nom_fichier = cle_doc+".pdf"
540 rep_fichier = cle_doc[0:2]
541 fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
543 os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
544 elif os.name == 'posix':
545 script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
546 pid = os.system(script)
547 except AttributeError:
548 traceback.print_exc()
551 def visu_a_plat(self):
553 Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant
555 if not hasattr(self,'JDC') : return
556 titre = 'fichier '+ self.JDCName + ' à plat '
557 self.jdc_fini = self.get_text_JDC('aplat')
558 if self.jdc_fini == None : return
559 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
561 def visu_txt_brut_JDC(self):
563 Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
565 if not hasattr(self,'JDC') : return
566 titre = "fichier de commandes utilisateur"
567 #texte = self.JDC.procedure
569 if self.JDCDisplay_courant.fichier == None:
570 self.appli.affiche_infos("Pas de fichier initial")
571 showerror("Impossible de visualiser le fichier initial",
572 "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC")
574 f=open(self.JDCDisplay_courant.fichier,'r')
577 self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
579 def affichage_fichier_ini(self):
581 Affichage des valeurs des paramètres relus par Eficas
583 self.appli.CONFIGURATION.affichage_fichier_ini()
585 def saveall(self,liste):
587 Sauvegarde tous les JDC contenus dans liste
590 for JDCDisplay in liste :
591 self.JDC = JDCDisplay.jdc
592 test = test * self.saveJDC(echo = 'non')
596 # ---------------------------------------------------------------------------
597 # Méthodes liées aux mots-clés inconnus
598 # ---------------------------------------------------------------------------
600 def mc_inconnus(self):
601 l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
602 o = fenetre_mc_inconnus(l_mc)
603 l = o.wait_new_list()
604 #print "mc_inconnus_new_list: ",l
605 #CCAR: Il n' y a pas de retour vers le JDC
607 def aideEFICAS(self):
608 AIDE.go(master=self.parent)
610 def update_jdc_courant(self):
611 self.JDCDisplay_courant.update()