2 Ce module contient la classe BUREAU qui gere les JDC ouverts
8 from tkFileDialog import askopenfilename,asksaveasfilename
9 from tkMessageBox import showinfo,askyesno,showerror
15 from jdcdisplay import JDCDISPLAY
16 from utils import extension,stripPath,save_in_file
17 from widgets import Fenetre,Ask_Format_Fichier
18 from fenetre_mc_inconnus import fenetre_mc_inconnus
25 ('Enregistrer','saveJDC'),
26 ('Enregistrer sous','saveasJDC'),
28 ('Fermer','closeJDC'),
29 ('Quitter','exitEFICAS'),
39 ('Rapport de validation','visuCRJDC'),
40 ('Fichier à plat','visu_a_plat'),
41 ('Fichier .py','visuJDC_py'),
42 ('Fichier source','visu_txt_brut_JDC'),
43 ('Paramètres Eficas','affichage_fichier_ini'),
44 ('Mots-clés inconnus','mc_inconnus'),
49 button_defs = (('New24',"newJDC","Création d'un nouveau fichier",'always'),
50 ('Open24',"openJDC","Ouverture d'un fichier existant",'always'),
51 ('Save24',"saveJDC","Sauvegarde du fichier courant",'always'),
52 ('Zoom24',"visuJDC","Visualisation du fichier de commandes",'always'),
54 ('Copy24',"copy","Copie l'objet courant",'jdc'),
55 ('Cut24',"cut","Coupe l'objet courant",'jdc'),
56 ('Paste24',"paste","Colle l'objet copié après l'objet courant",'jdc'),
58 ('Delete24',"delete","Supprime l'objet courant",'jdc'),
59 ('Help24',"view_doc","Documentation de l'objet courant",'jdc')
62 def __init__(self,appli,parent):
65 splash._splash.configure(text = "Création du bureau")
66 self.nb = Pmw.NoteBook(self.parent,raisecommand=self.selectJDC)
67 self.nb.pack(fill='both',expand=1)
68 self.JDCDisplay_courant=None
70 self.liste_JDCDisplay=[]
73 def cree_cataitem(self):
75 On récupère dans l'extension readercata les variables
76 qui servent par la suite pour la création des JDC
78 self.cataitem=self.appli.readercata.cataitem
79 self.cata=self.appli.readercata.cata
80 self.cata_ordonne_dico=self.appli.readercata.cata_ordonne_dico
81 self.code=self.appli.readercata.code
82 self.version_code=self.appli.readercata.version_code
83 self.fic_cata=self.appli.readercata.fic_cata
85 def selectJDC(self,event=None):
87 Cette méthode est appelée chaque fois que l'on sélectionne
88 l'onglet d'un JDC dans le NoteBook des JDC.
89 Elle permet de stocker dans les variable self.JDC et
90 self.JDCDisplay_courant les valeurs concernant le JDC courant
92 if len(self.liste_JDCDisplay) == 0 : return
93 #if self.JDCDisplay_courant : self.JDCDisplay_courant.jdc.unset_context()
94 numero_jdc = self.nb.index(self.nb.getcurselection())
95 self.JDCDisplay_courant = self.liste_JDCDisplay[numero_jdc]
96 self.JDC = self.JDCDisplay_courant.jdc
97 #self.JDC.set_context()
98 self.JDCName = self.JDC.nom
102 Initialise un nouveau JDC vierge
104 self.appli.statusbar.reset_affichage_infos()
106 CONTEXT.unset_current_step()
107 J=self.cata[0].JdC(cata=self.cata,
108 cata_ord_dico=self.cata_ordonne_dico,
111 self.ShowJDC(J,self.JDCName)
112 self.appli.toolbar.active_boutons()
114 def ShowJDC(self,JDC,nom,label_onglet=None):
116 Lance l'affichage du JDC cad création du JDCDisplay
117 Rajoute le JDCDisplay à la liste des JDCDisplay si label_onglet == None cad si on crée
118 bien un nouveau JDCDisplay et non si on remplace (renommage de l'onglet)
121 self.JDCName = self.JDC.nom = nom
122 #XXX CCAR: pour le moment mis en commentaire
123 #self.JDC.set_context()
124 if label_onglet == None :
125 label_onglet = self.GetLabelJDC()
126 self.nb.add(label_onglet,tab_text = nom,tab_width=20)
130 self.JDCDisplay_courant=JDCDISPLAY(self.JDC,nom,appli=self.appli,parent=self.nb.page(label_onglet))
132 self.liste_JDCDisplay.append(self.JDCDisplay_courant)
133 self.JDCDisplay_courant.modified='n'
134 self.JDCDisplay_courant.fichier=self.fileName
135 self.nb.selectpage(label_onglet)
136 self.nb.setnaturalsize()
137 texte = "Jeu de commandes :" + self.JDCName+" ouvert"
138 self.appli.affiche_infos(texte)
140 def closeJDC (self) :
142 Ferme le JDC courant et détruit l'onglet associé dans le notebook self.nb
144 if self.JDCDisplay_courant.modified == 'o' :
145 message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
146 reponse = askyesno(title="Sauvegarde du jdc courant",
149 test = self.saveJDC()
151 self.appli.affiche_infos("Sauvegarde impossible")
153 self.JDCDisplay_courant.jdc.supprime()
154 self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
155 self.nb.delete(self.nb.getcurselection())
156 #XXX CCAR: pour le moment mis en commentaire
157 #self.JDC.unset_context()
160 index = self.nb.index(self.nb.getcurselection())
161 self.JDCDisplay_courant = self.liste_JDCDisplay[index]
162 self.JDC = self.JDCDisplay_courant.jdc
164 self.JDCDisplay_courant = None
165 self.appli.toolbar.inactive_boutons()
168 return self.visuCR(mode='JDC')
170 def visuCR(self,mode):
172 Méthode permettant l'affichage du rapport de validation
175 if not hasattr(self,'JDC') : return
176 titre="rapport de validation du jeu de commandes courant"
177 cr = self.JDC.report()
179 from Noyau.N_CR import CR
181 cr.debut = "Début rapport de validation du catalogue"
182 cr.fin = "Fin rapport de validation du catalogue"
183 titre="rapport de validation du catalogue"
184 if hasattr(self,'cata_ordonne_cr') :
185 cr.add(self.cata_ordonne_cr)
186 if hasattr(self,'cata_dev_ordonne_cr') :
187 cr.add(self.cata_dev_ordonne_cr)
188 for cata in self.cata:
189 if hasattr(cata,'JdC'):
190 cr.add(cata.JdC.report())
192 self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
194 def openJDC(self,file=None):
196 Demande à l'utilisateur quel JDC existant il veut ouvrir
198 if self.code == 'ASTER':
199 filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),)
201 filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
202 if not hasattr(self,'initialdir'):
203 self.initialdir = self.appli.CONFIGURATION.rep_user
205 file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
206 defaultextension=".comm",
207 filetypes = filetypes,
208 initialdir = self.initialdir)
212 self.JDCName=stripPath(file)
213 self.initialdir = os.path.dirname(file)
216 #XXX CCAR: pour le moment mis en commentaire
217 #if self.JDCDisplay_courant:self.JDCDisplay_courant.jdc.unset_context()
219 format=self.appli.format_fichier.get()
220 # Il faut convertir le contenu du fichier en fonction du format
221 if convert.plugins.has_key(format):
222 # Le convertisseur existe on l'utilise
223 p=convert.plugins[format]()
225 text=p.convert('exec')
226 if not p.cr.estvide():
227 self.appli.affiche_infos("Erreur à la conversion")
229 titre="compte-rendu d'erreurs, EFICAS ne sait pas convertir ce fichier",
230 texte = str(p.cr)).wait()
233 # Il n'existe pas c'est une erreur
234 self.appli.affiche_infos("Type de fichier non reconnu")
235 showerror("Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
238 # On se met dans le repertoire ou se trouve le fichier de commandes
239 # pour trouver les eventuels fichiers include ou autres
240 # localises a cote du fichier de commandes
241 os.chdir(self.initialdir)
242 CONTEXT.unset_current_step()
243 J=self.cata[0].JdC(procedure=text,appli=self.appli,
244 cata=self.cata,cata_ord_dico=self.cata_ordonne_dico,
247 txt_exception = J.cr.get_mess_exception()
249 # des exceptions ont été levées à la création du JDC
250 # --> on affiche les erreurs mais pas le JDC
251 self.appli.affiche_infos("Erreur fatale au chargement de %s" %file)
252 showerror("Erreur fatale au chargement d'un fichier",txt_exception)
254 self.ShowJDC(J,self.JDCName)
255 self.appli.toolbar.active_boutons()
256 # si le JDC ne contient rien (vide), on retourne ici
257 if len(self.JDC.etapes) == 0 : return
258 # dans le cas où le JDC est invalide, on affiche son CR
259 cr = self.JDC.report()
260 if not cr.estvide() :
261 self.appli.top.update()
262 self.visuCR(mode='JDC')
265 def GetLabelJDC(self,nb_jdc = 'absent'):
267 Retourne le label de l'onglet du NoteBook associé au JDC à afficher
269 if nb_jdc == 'absent':
270 nb_jdc = len(self.nb.pagenames())
272 label_onglet = 'JDC'+`nb_jdc`
273 if label_onglet not in self.nb.pagenames() :
276 return self.GetLabelJDC(nb_jdc)
280 Sauvegarde le JDC courant en demandant impérativement à l'utilisateur de
281 donner le nom du fichier de sauvegarde
283 self.saveJDC(echo='oui')
285 def saveJDC(self,echo='non'):
287 Sauvegarde le JDC courant.
288 Retourne 1 si la sauvegarde s'est bien faite, 0 sinon.
289 Si echo = 'oui' : interactif (l'utilisateur donne le nom sous lequel il
291 Si echo = 'non' : muet (sauvegarde le JDC dans JDC.procedure)
293 if not hasattr(self,'JDC') : return 0
294 format=self.appli.format_fichier.get()
295 if generator.plugins.has_key(format):
296 # Le generateur existe on l'utilise
297 g=generator.plugins[format]()
298 jdc_formate=g.gener(self.JDC,format='beautifie')
299 if not g.cr.estvide():
301 self.appli.affiche_infos("Erreur à la generation")
302 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
305 # Il n'existe pas c'est une erreur
306 self.appli.affiche_infos("Format %s non reconnu" % format)
307 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC")
309 self.jdc_fini = string.replace(jdc_formate,'\r\n','\n')
311 if echo =='oui' or self.JDCDisplay_courant.fichier == None:
312 return self.asknomsauvegardeJDC()
313 elif self.JDCDisplay_courant.fichier != None :
314 # le JDC a déjà un nom : on sauvegarde directement sans demander
315 # un autre nom au développeur
316 if not save_in_file(self.JDCDisplay_courant.fichier,self.jdc_fini) :
317 showinfo("Erreur","Problème à la sauvegarde du fichier :" + `self.JDCDisplay_courant.fichier`)
320 self.JDCDisplay_courant.stop_modif()
321 self.appli.affiche_infos("sauvegarde de "+`self.JDCDisplay_courant.fichier`+" effectuée")
324 def asknomsauvegardeJDC(self):
325 """ Demande à l'utilsateur le nom sous lequel il veut sauvegarder le JDC courant """
326 titre = "Sauvegarde d'un fichier de commandes "+self.code
327 if self.code == 'ASTER':
329 filtyp = ( ("ASTER", ".comm"),)
332 filtyp = ( (self.code, ".py"),)
333 sauvegarde = asksaveasfilename(title=titre,
334 defaultextension=defext,
336 initialdir = self.appli.CONFIGURATION.rep_user)
338 if not save_in_file(sauvegarde,self.jdc_fini) :
339 showinfo("Erreur","Problème à la sauvegarde du fichier "+`sauvegarde`)
342 self.JDCDisplay_courant.stop_modif()
343 self.appli.affiche_infos("Sauvegarde effectuée")
344 if sauvegarde != self.JDCDisplay_courant.fichier :
345 # l'utilisateur a sauvegardé le JDC sous un autre nom
346 self.JDCDisplay_courant.fichier = sauvegarde
347 self.JDCName = self.JDC.nom = stripPath(sauvegarde)
353 def changeNomPage(self):
354 """ Change le nom de l'onglet contenant le JDC courant : en fait détruit l'actuel
355 et recrée un autre onglet à la même place avec le bon nom
358 self.JDCDisplay_courant.jdc.nom = nom
359 nom_page = self.nb.getcurselection()
360 num_page = self.nb.index(nom_page)
361 tab = self.nb.tab(num_page)
362 tab.configure(text = nom)
364 def exitEFICAS(self):
366 Permet de sortir d'EFICAS en demandant à l'utilisateur
367 s'il veut sauvegarder les modifications en cours
369 liste = self.GetListeJDCaSauvegarder()
371 # Certains fichiers n'ont pas été sauvegardés ...
372 if askyesno("Enregistrer modifications","Enregister les modifications ?") :
373 test = self.saveall(liste)
376 if askyesno ("Quitter","Voulez-vous vraiment quitter l'application ?") :
377 for JDCDisplay in self.liste_JDCDisplay:
378 JDCDisplay.jdc.supprime()
382 def GetListeJDCaSauvegarder(self) :
383 """ Retourne parmi la liste de tous les JDC ouverts la liste de ceux qui ont été modifiés """
384 if not self.JDCDisplay_courant : return []
385 if len(self.liste_JDCDisplay) == 0 : return l
387 for JDCDisplay in self.liste_JDCDisplay:
388 if JDCDisplay.modified == 'o' :
394 Lance la copie sur le JDC courant
396 if self.JDCDisplay_courant : self.JDCDisplay_courant.doCopy()
400 Lance le collage sur le JDC courant
402 if self.JDCDisplay_courant : self.JDCDisplay_courant.doPaste()
406 Lance le cut sur le JDC courant
408 if self.JDCDisplay_courant: self.JDCDisplay_courant.doCut()
412 Lance la suppression du noeud courant
414 if not self.JDCDisplay_courant : return
416 if self.JDCDisplay_courant.modified == 'n' :
417 self.JDCDisplay_courant.init_modif()
418 pere = self.JDCDisplay_courant.node_selected.parent
419 self.JDCDisplay_courant.node_selected.delete()
421 except AttributeError:
424 def visuJDC_py(self):
426 Méthode permettant d'afficher dans une fenêtre à part l'écho au
427 format python du jdc courant
429 if not hasattr(self,'JDC') : return
430 jdc_fini = self.get_text_JDC('python')
431 if jdc_fini == None : return
433 titre = 'fichier '+ self.JDCName + ' à la syntaxe Python',
438 Méthode permettant d'afficher dans une fenêtre à part l'écho au
439 format .comm ou .py du jdc courant
441 if not hasattr(self,'JDC') : return
442 titre = 'fichier '+ self.JDCName + ' à la syntaxe '+ self.code
443 format=self.appli.format_fichier.get()
444 self.jdc_fini = self.get_text_JDC(format)
445 if self.jdc_fini == None : return
446 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
448 def get_text_JDC(self,format):
449 if generator.plugins.has_key(format):
450 # Le generateur existe on l'utilise
451 g=generator.plugins[format]()
452 jdc_formate=g.gener(self.JDC,format='beautifie')
453 if not g.cr.estvide():
455 self.appli.affiche_infos("Erreur à la generation")
456 showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
461 # Il n'existe pas c'est une erreur
462 self.appli.affiche_infos("Format %s non reconnu" % format)
463 showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
468 Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
469 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
470 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique
472 if not self.JDCDisplay_courant : return
474 cle_doc = self.JDCDisplay_courant.node_selected.item.get_docu()
475 if cle_doc == None : return
476 cle_doc = string.replace(cle_doc,'.','')
477 cle_doc = string.replace(cle_doc,'-','')
478 commande = self.appli.CONFIGURATION.exec_acrobat
479 nom_fichier = cle_doc+".pdf"
480 rep_fichier = cle_doc[0:2]
481 fichier = os.path.abspath(os.path.join(self.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
483 os.spawnv(os.P_NOWAIT,commande,(commande,fichier,))
484 elif os.name == 'posix':
485 script ="#!/usr/bin/sh \n%s %s&" %(commande,fichier)
486 pid = os.system(script)
487 except AttributeError:
488 traceback.print_exc()
491 def visu_a_plat(self):
493 Méthode permettant d'afficher dans une fenêtre à part l'écho 'à plat' du jdc courant
495 if not hasattr(self,'JDC') : return
496 titre = 'fichier '+ self.JDCName + ' à plat '
497 self.jdc_fini = self.get_text_JDC('aplat')
498 if self.jdc_fini == None : return
499 self.visu_fichier_cmd = Fenetre(self.appli,titre=titre,texte = self.jdc_fini)
501 def visu_txt_brut_JDC(self):
503 Méthode permettant d'afficher le jeu de commandes tel qu'il a été passé au JDC
505 if not hasattr(self,'JDC') : return
506 titre = "fichier de commandes utilisateur"
507 texte = self.JDC.procedure
509 self.appli.affiche_infos("Pas de fichier initial")
510 showerror("Impossible de visualiser le fichier initial","EFICAS ne peut visualiser le fichier \
511 initial.\nIl s'agit d'un nouveau JDC")
513 self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte)
515 def affichage_fichier_ini(self):
517 Affichage des valeurs des paramètres relus par Eficas
519 self.appli.CONFIGURATION.affichage_fichier_ini()
521 def saveall(self,liste):
523 Sauvegarde tous les JDC contenus dans liste
526 for JDCDisplay in liste :
527 self.JDC = JDCDisplay.jdc
528 test = test * self.saveJDC(echo = 'non')
532 # ---------------------------------------------------------------------------
533 # Méthodes liées aux mots-clés inconnus
534 # ---------------------------------------------------------------------------
536 def mc_inconnus(self):
537 l_mc = self.JDCDisplay_courant.jdc.get_liste_mc_inconnus()
538 o = fenetre_mc_inconnus(l_mc)
539 l = o.wait_new_list()