1 # -*- coding: utf-8 -*-
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
22 Ce module contient la classe APPLI qui est la classe mère de
23 l'application EFICAS. Elle prend en charge l'organisation générale
24 des composants graphiques et l'initialisation Tk
25 L'aspect applicatif doit etre pris en charge par la classe dérivée
34 from widgets import showerror
40 from styles import style
44 import convert,generator
45 from Editeur import comploader
46 from Editeur.utils import extension_fichier,stripPath
48 from widgets import Fenetre
49 from Misc import MakeNomComplet
50 from Editeur import session
55 REPTK=os.path.dirname(os.path.abspath(__file__))
58 VERSION="EFICAS v1.14"
61 def __init__ (self,master,code=prefs.code,fichier=None,test=0,ihm="TK",salome=0) :
66 self.top.protocol("WM_DELETE_WINDOW",self.exitEFICAS)
68 #dimensionnement de la fenetre principale
69 #aspect ratio de l'ecran
70 aspect=float(self.top.winfo_screenwidth())/float(self.top.winfo_screenheight())
71 #resolution (pixels par point). On utilise le fait qu'on a "normalement" 72 points par inch
72 resolution= self.top.winfo_screenwidth()/(self.top.winfo_screenmmwidth()/25.4*72)
73 DDY=max(20,resolution*(fontes.standard[1]+4)) #largeur d'un caractere fonte standard en pixel
74 x=int(45*DDY) #largeur d'ouverture de 45 caracteres de fonte standard
75 y=int(25*DDY) #hauteur d'ouverture de 25 caracteres de fonte standard
76 minx=x*8/10 #largeur min (80 pour cent de largeur)
77 miny=y*8/10 #hauteur min (80 pour cent de hauteur)
78 self.top.minsize(minx,miny)
79 self.top.geometry('%dx%d' % (x,y))
81 self.top.title(VERSION + ' pour '+self.code)
82 self.titre=VERSION + ' pour '+self.code
84 self.initializeTk(master)
85 Pmw.initialise(master)
88 self.liste_simp_reel=[]
89 # L'attribut test permet d'activer les panneaux de splash et d'erreur (test=0)
90 # Si test est different de 0, les panneaux ne sont pas activés
93 # Lecture des parametres de configuration (fichier global editeur.ini
94 # et utilisateur eficas.ini)
95 self.lecture_parametres()
97 self.format_fichier = Tkinter.StringVar()
99 # Avant la creation du bureau qui lit le catalogue
100 self.version_code=session.d_env.cata
102 # Creation de la menubar, toolbar, messagebar
103 self.cree_composants_graphiques()
104 # Creation des autres composants graphiques dont le bureau (parametrable par prefs.py)
105 self.load_appli_composants()
106 self.listeFichiers=listeFichiers.listeFichiers(self)
107 self.listePatrons=listePatronsTK.listePatronsTK(self)
110 # Fermer le splash et deiconifier la fenetre principale si on n'est pas en test
115 # Ouverture des fichiers de commandes donnes sur la ligne de commande
118 for study in session.d_env.studies:
120 d=session.get_unit(study,self)
121 self.bureau.openJDC(file=study["comm"],units=d)
124 def send_message(self,message):
127 def exitEFICAS(self):
134 def lecture_parametres(self):
136 Active la lecture des paramètres standards et utilisateur
139 splash._splash.configure(text = "Chargement des paramètres utilisateur")
140 from Editeur import configuration
141 self.CONFIGURATION = configuration.make_config(self,prefs.REPINI)
142 self.CONFIGStyle = configuration.make_config_style(self,prefs.REPINI)
144 def cree_composants_graphiques(self):
146 Cree les constituants graphiques fixes de l'application :
152 splash._splash.configure(text = "Chargement de l'IHM")
153 splash._splash.configure(text = "Chargement de la menubar")
155 self.menubar=menubar.MENUBAR(self,self.top)
157 splash._splash.configure(text = "Chargement de la toolbar")
159 self.toolbar=toolbar.TOOLBAR(self,self.top)
161 splash._splash.configure(text = "Chargement de la statusbar")
163 self.statusbar=statusbar.STATUSBAR(self.top,styles.style.statusfont)
165 def load_appli_composants(self):
167 Cree les autres constituants graphiques de l'application :
171 Cette creation est parametrable par fichier prefs.py
174 splash._splash.configure(text = "Chargement des appli_composants")
175 for mname in self.appli_composants:
176 self.load_appli_composant(mname)
178 def load_appli_composant(self,mname):
179 module=__import__(mname,globals(),locals())
180 factory=getattr(module,mname.upper())
181 appli_composant=factory(self,self.top)
182 setattr(self,mname,appli_composant)
183 self.fill_menus(appli_composant,appli_composant.menu_defs)
184 self.toolbar.creer_boutons_appli_composant(appli_composant.button_defs,appli_composant)
186 def affiche_FAQ(self):
188 faq.affiche(self.top)
190 def affiche_infos(self,message):
191 self.statusbar.affiche_infos(message)
194 def initializeTk(self, root):
196 Initialize platform specific options
198 if sys.platform == 'mac':
199 self.initializeTk_mac(root)
200 elif sys.platform == 'win32':
201 self.initializeTk_win32(root)
203 self.initializeTk_unix(root)
205 def initializeTk_win32(self, root):
206 root.option_add('*Font', fontes.standard)
207 root.option_add('*EntryField.Entry.Font', fontes.standard)
208 root.option_add('*Listbox*Font',fontes.standard)
210 def initializeTk_colors_common(self, root):
211 root.option_add('*background', style.background)
212 root.option_add('*foreground', style.foreground)
213 root.option_add('*EntryField.Entry.background', style.entry_background)
214 root.option_add('*Entry*background', style.entry_background)
215 root.option_add('*Listbox*background', style.list_background)
216 root.option_add('*Listbox*selectBackground', style.list_select_background)
217 root.option_add('*Listbox*selectForeground', style.list_select_foreground)
219 def initializeTk_mac(self, root):
220 self.initializeTk_colors_common(root)
222 def initializeTk_unix(self, root):
223 root.option_add('*Font', fontes.standard)
224 root.option_add('*EntryField.Entry.Font',fontes.standard )
225 root.option_add('*Listbox*Font', fontes.standard)
226 self.initializeTk_colors_common(root)
228 def get_texte_infos(self):
230 Retourne un texte d'informations sur la session courante d'EFICAS
232 texte = VERSION + '\n\n'
233 texte = texte + 'EFICAS est un produit développé par \nEDF-R&D\n'
234 texte = texte + 'Equipe : SINETICS\n\n'
235 texte = texte + 'Code utilisé : %s version %s\n' % (self.code,properties.version)
238 def efface_aide(self,event):
240 Efface la bulle d'aide d'un panneau
248 def affiche_aide(self,event,aide):
250 Affiche l'aide concernant un panneau
255 self.aide=tooltip.TOOLTIP(widget)
256 self.aide.xoffset = 10
257 self.aide.yoffset = - widget.winfo_height()/2
258 self.aide.setText(aide)
262 def cree_menu(self,menu,itemlist,appli_composant):
264 Ajoute les items du tuple itemlist
269 for item in itemlist:
270 number_item=number_item + 1
273 #menu.add_separator()
278 raccourci_label=" "+raccourci
279 newitem=(item[0],item[1])
283 raccourci_label=" "+item[3]
284 newitem=(item[0],item[1])
290 if type(method) == types.TupleType:
291 # On a un tuple => on cree une cascade
292 menu_cascade=Tkinter.Menu(menu)
293 menu.add_cascade(label=label,menu=menu_cascade)
294 self.cree_menu(menu_cascade,method,appli_composant)
295 elif method[0] == '&':
296 # On a une chaine avec & en tete => on cree un radiobouton
297 command=getattr(appli_composant,method[1:])
298 menu.add_radiobutton(label=label,command=command)
299 if radio == None:radio=number_item
301 command=getattr(appli_composant,method)
302 menu.add_command(label=label,accelerator=raccourci_label,command=command)
304 self.top.bind(raccourci,command)
305 # Si au moins un radiobouton existe on invoke le premier
306 if radio:menu.invoke(radio)
308 def fill_menus(self,appli_composant,defs):
309 menudict=self.menubar.menudict
310 for mname,itemlist in defs:
311 if mname in menudict.keys() :
315 self.cree_menu(menu,itemlist,appli_composant)
317 def update_jdc_courant(self):
318 self.bureau.update_jdc_courant()
320 def affiche_alerte(self,titre,message):
321 f=Fenetre(self, titre="Compte-rendu d'erreur", texte = titre + "\n\n" + message)
326 def __init__(self,v=None):
333 class STANDALONE(APPLI):
334 def __init__ (self,code=prefs.code,fichier=None,version='v8.2',ihm="TK") :
339 self.format_fichier=valeur()
342 self.liste_simp_reel=[]
343 # L'attribut test doit valoir 1 si on ne veut pas creer les fenetres
345 self.titre="STANDALONE POUR TEST"
347 # Lecture des parametres de configuration (fichier global editeur.ini
348 # et utilisateur eficas.ini)
349 self.lecture_parametres()
352 # Avant la creation du bureau qui lit le catalogue
353 self.version_code=version
355 self.readercata=readercata.READERCATA(self,None)
359 def affiche_infos(self,message):
362 def get_text_JDC(self,JDC,format):
363 if generator.plugins.has_key(format):
364 # Le generateur existe on l'utilise
365 g=generator.plugins[format]()
366 jdc_formate=g.gener(JDC,format='beautifie')
369 # Il n'existe pas c'est une erreur
373 CONTEXT.unset_current_step()
374 J=self.readercata.cata[0].JdC(procedure="",
376 cata=self.readercata.cata,
377 cata_ord_dico=self.readercata.cata_ordonne_dico,
378 rep_mat=self.CONFIGURATION.rep_mat,
383 def openJDC(self,file):
385 e=extension_fichier(file)
386 self.JDCName=stripPath(file)
387 self.initialdir = os.path.dirname(os.path.abspath(file))
388 format=self.format_fichier.get()
389 # Il faut convertir le contenu du fichier en fonction du format
390 if convert.plugins.has_key(format):
391 # Le convertisseur existe on l'utilise
392 p=convert.plugins[format]()
394 text=p.convert('exec',self)
395 if not p.cr.estvide():
396 raise ValueError(str(p.cr))
398 # On se met dans le repertoire ou se trouve le fichier de commandes
399 # pour trouver les eventuels fichiers include ou autres
400 # localises a cote du fichier de commandes
401 os.chdir(self.initialdir)
402 CONTEXT.unset_current_step()
403 J=self.readercata.cata[0].JdC(procedure=text,
405 cata=self.readercata.cata,
406 cata_ord_dico=self.readercata.cata_ordonne_dico,
408 rep_mat=self.CONFIGURATION.rep_mat,
411 txt= J.cr.get_mess_exception()
412 if txt:raise ValueError(txt)
415 def openTXT(self,text):
417 CONTEXT.unset_current_step()
418 J=self.readercata.cata[0].JdC(procedure=text,
420 cata=self.readercata.cata,
421 cata_ord_dico=self.readercata.cata_ordonne_dico,
423 rep_mat=self.CONFIGURATION.rep_mat,
426 txt= J.cr.get_mess_exception()
427 if txt:raise ValueError(txt)
430 def create_item(self,obj):
431 return comploader.make_objecttreeitem(self,getattr(obj,"nom","item"),obj)
433 def get_file(self,unite=None,fic_origine = ''):
435 Retourne le nom du fichier correspondant a l unite logique unite (entier)
436 ou d'un fichier poursuite
438 f,ext=os.path.splitext(fic_origine)
441 finclude=f+".%d" % unite
448 ext=".com%d" % (string.atoi(n)-1)
449 if ext == '.com0' and not os.path.isfile(f+".com0"):
457 def affiche_alerte(self,titre,message):
458 print titre+ "\n\n" + message