]> SALOME platform Git repositories - tools/eficas.git/blob - InterfaceTK/appli.py
Salome HOME
CCAR: merge de la version 1.14 dans la branche principale
[tools/eficas.git] / InterfaceTK / appli.py
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.
9 #
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.
14 #
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.
18 #
19 #
20 # ======================================================================
21 """
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
26 """
27 # Modules Python
28 import os
29 import string
30 import sys
31 import types
32 import Pmw
33 import Tkinter
34 from widgets import showerror
35
36 # Modules Eficas
37 import splash
38 import prefs
39 import styles
40 from styles import style
41 import fontes
42 import tooltip
43 import properties
44 import convert,generator
45 from Editeur import comploader
46 from Editeur.utils import extension_fichier,stripPath
47
48 from widgets import Fenetre
49 from Misc import MakeNomComplet
50 from Editeur import session
51
52 import listeFichiers
53 import listePatronsTK
54
55 REPTK=os.path.dirname(os.path.abspath(__file__))
56 sys.path[:0]=[REPTK]
57
58 VERSION="EFICAS v1.14"
59
60 class APPLI: 
61   def __init__ (self,master,code=prefs.code,fichier=None,test=0,ihm="TK",salome=0) :
62       self.ihm=ihm
63       self.code=code
64       self.salome=salome
65       self.top=master
66       self.top.protocol("WM_DELETE_WINDOW",self.exitEFICAS)
67
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))
80
81       self.top.title(VERSION + ' pour '+self.code)
82       self.titre=VERSION + ' pour '+self.code
83       self.top.withdraw()
84       self.initializeTk(master)
85       Pmw.initialise(master)
86
87       self.dict_reels={}
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
91       self.test=test
92
93       # Lecture des parametres de configuration (fichier global editeur.ini 
94       # et utilisateur eficas.ini)
95       self.lecture_parametres()
96
97       self.format_fichier = Tkinter.StringVar()
98       self.message=''
99       # Avant la creation du bureau qui lit le catalogue
100       self.version_code=session.d_env.cata
101
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)
108       self.dir=None
109
110       # Fermer le splash et deiconifier la fenetre principale si on n'est pas en test
111       if (self.test == 0):
112            splash.fini_splash()
113            #self.affiche_FAQ()
114
115       # Ouverture des fichiers de commandes donnes sur la ligne de commande
116       cwd=os.getcwd()
117       self.dir=cwd
118       for study in session.d_env.studies:
119           os.chdir(cwd)
120           d=session.get_unit(study,self)
121           self.bureau.openJDC(file=study["comm"],units=d)
122
123
124   def send_message(self,message):
125       self.message=message
126
127   def exitEFICAS(self):
128       self.quit()
129
130   def quit(self):
131       if self.top:
132         self.top.quit()
133
134   def lecture_parametres(self):
135       """
136           Active la lecture des paramètres standards et utilisateur
137       """
138       if (self.test == 0):
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)
143
144   def cree_composants_graphiques(self):
145       """
146           Cree les constituants graphiques fixes de l'application :
147            - menubar
148            - toolbar
149            - statusbar
150       """
151       if (self.test == 0):
152          splash._splash.configure(text = "Chargement de l'IHM")
153          splash._splash.configure(text = "Chargement de la menubar")
154       import menubar
155       self.menubar=menubar.MENUBAR(self,self.top)
156       if (self.test == 0):
157          splash._splash.configure(text = "Chargement de la toolbar")
158       import toolbar
159       self.toolbar=toolbar.TOOLBAR(self,self.top)
160       if (self.test == 0):
161          splash._splash.configure(text = "Chargement de la statusbar")
162       import statusbar
163       self.statusbar=statusbar.STATUSBAR(self.top,styles.style.statusfont)
164
165   def load_appli_composants(self):
166       """
167           Cree les autres constituants graphiques de l'application :
168            - bureau 
169            - readercata
170            - ...
171           Cette creation est parametrable par fichier prefs.py
172       """
173       if (self.test == 0):
174          splash._splash.configure(text = "Chargement des appli_composants")
175       for mname in self.appli_composants:
176          self.load_appli_composant(mname)
177
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)
185
186   def affiche_FAQ(self):
187       import faq
188       faq.affiche(self.top)
189
190   def affiche_infos(self,message):
191       self.statusbar.affiche_infos(message)
192       return
193
194   def  initializeTk(self, root):
195         """
196         Initialize platform specific options
197         """
198         if sys.platform == 'mac':
199             self.initializeTk_mac(root)
200         elif sys.platform == 'win32':
201             self.initializeTk_win32(root)
202         else:
203             self.initializeTk_unix(root)
204
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)
209
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)
218
219   def initializeTk_mac(self, root):
220         self.initializeTk_colors_common(root)
221
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)
227
228   def get_texte_infos(self):
229       """
230           Retourne un texte d'informations sur la session courante d'EFICAS
231       """
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)
236       return texte
237
238   def efface_aide(self,event):
239       """
240           Efface la bulle d'aide d'un panneau
241       """
242       try:
243           self.aide.destroy()
244       except:
245           pass
246       return
247
248   def affiche_aide(self,event,aide):
249       """
250           Affiche l'aide concernant un panneau
251       """
252       x=event.x
253       y=event.y
254       widget=event.widget
255       self.aide=tooltip.TOOLTIP(widget)
256       self.aide.xoffset = 10
257       self.aide.yoffset = - widget.winfo_height()/2
258       self.aide.setText(aide)
259       self.aide._showTip()
260       return 
261
262   def cree_menu(self,menu,itemlist,appli_composant):
263       """
264           Ajoute les items du tuple itemlist
265           dans le menu menu
266       """
267       number_item=0
268       radio=None
269       for item in itemlist:
270          number_item=number_item + 1
271          raccourci_label=""
272          if not item :
273             #menu.add_separator()
274             pass
275          else:
276             if len(item)==3:
277                raccourci=item[2]
278                raccourci_label="   "+raccourci
279                newitem=(item[0],item[1])
280             else :
281                if len(item)==4:
282                   raccourci=item[2]
283                   raccourci_label="   "+item[3]
284                   newitem=(item[0],item[1])
285                else :
286                   raccourci=""
287                   newitem=item
288             item=newitem
289             label,method=item
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
300             else:
301                command=getattr(appli_composant,method)
302                menu.add_command(label=label,accelerator=raccourci_label,command=command)
303                if raccourci != "" :
304                   self.top.bind(raccourci,command)
305       # Si au moins un radiobouton existe on invoke le premier
306       if radio:menu.invoke(radio)
307
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() : 
312              menu=menudict[mname]
313           else :
314              continue
315           self.cree_menu(menu,itemlist,appli_composant)
316
317   def update_jdc_courant(self):
318       self.bureau.update_jdc_courant()
319
320   def affiche_alerte(self,titre,message):
321       f=Fenetre(self, titre="Compte-rendu d'erreur", texte = titre + "\n\n" + message)
322       f.wait()
323
324
325 class valeur:
326    def __init__(self,v=None):
327       self.v=v
328    def set(self,v):
329       self.v=v
330    def get(self):
331       return self.v
332
333 class STANDALONE(APPLI):
334    def __init__ (self,code=prefs.code,fichier=None,version='v8.2',ihm="TK") :
335       self.ihm=ihm
336       self.salome=0
337       self.code=code
338       self.top=None
339       self.format_fichier=valeur()
340
341       self.dict_reels={}
342       self.liste_simp_reel=[]
343       # L'attribut test doit valoir 1 si on ne veut pas creer les fenetres
344       self.test=1
345       self.titre="STANDALONE POUR TEST"
346
347       # Lecture des parametres de configuration (fichier global editeur.ini
348       # et utilisateur eficas.ini)
349       self.lecture_parametres()
350
351       self.message=''
352       # Avant la creation du bureau qui lit le catalogue
353       self.version_code=version
354       import readercata
355       self.readercata=readercata.READERCATA(self,None)
356
357       self.dir=None
358
359    def affiche_infos(self,message):
360       return
361
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')
367          return jdc_formate
368       else:
369          # Il n'existe pas c'est une erreur
370          return
371
372    def newJDC(self):
373       CONTEXT.unset_current_step()
374       J=self.readercata.cata[0].JdC(procedure="",
375                                     appli=self,
376                                     cata=self.readercata.cata,
377                                     cata_ord_dico=self.readercata.cata_ordonne_dico,
378                                     rep_mat=self.CONFIGURATION.rep_mat,
379                                    )
380       J.analyse()
381       return J
382
383    def openJDC(self,file):
384       self.fileName = 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]()
393          p.readfile(file)
394          text=p.convert('exec',self)
395          if not p.cr.estvide():
396              raise ValueError(str(p.cr))
397
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,
404                                     appli=self,
405                                     cata=self.readercata.cata,
406                                     cata_ord_dico=self.readercata.cata_ordonne_dico,
407                                     nom=self.JDCName,
408                                     rep_mat=self.CONFIGURATION.rep_mat,
409                                    )
410       J.analyse()
411       txt= J.cr.get_mess_exception()
412       if txt:raise ValueError(txt)
413       return J
414
415    def openTXT(self,text):
416       self.JDCName="TEXT"
417       CONTEXT.unset_current_step()
418       J=self.readercata.cata[0].JdC(procedure=text,
419                                     appli=self,
420                                     cata=self.readercata.cata,
421                                     cata_ord_dico=self.readercata.cata_ordonne_dico,
422                                     nom=self.JDCName,
423                                     rep_mat=self.CONFIGURATION.rep_mat,
424                                    )
425       J.analyse()
426       txt= J.cr.get_mess_exception()
427       if txt:raise ValueError(txt)
428       return J
429
430    def create_item(self,obj):
431       return comploader.make_objecttreeitem(self,getattr(obj,"nom","item"),obj)
432
433    def get_file(self,unite=None,fic_origine = ''):
434       """
435           Retourne le nom du fichier correspondant a l unite logique unite (entier)
436           ou d'un fichier poursuite
437       """
438       f,ext=os.path.splitext(fic_origine)
439       if unite :
440           #include
441           finclude=f+".%d" % unite
442       else:
443           #poursuite
444           n=ext[-1]
445           if n == '0':
446              ext=".comm"
447           else: 
448              ext=".com%d" % (string.atoi(n)-1)
449              if ext == '.com0' and not os.path.isfile(f+".com0"):
450                 ext=".comm"
451           finclude=f+ext
452       ff=open(finclude)
453       text=ff.read()
454       ff.close()
455       return finclude,text
456
457    def affiche_alerte(self,titre,message):
458       print titre+ "\n\n" + message