Salome HOME
052d2f1d26d135918e93a15256630393e42b7813
[tools/eficas.git] / InterfaceQT4 / readercata.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 sert a lire un catalogue et a construire
23     un objet CataItem pour Eficas.
24     Il s'appuie sur la classe READERCATA
25 """
26 # Modules Python
27 import time
28 import os,sys,py_compile
29 import traceback
30 import cPickle
31 import re
32
33 # Modules Eficas
34 import prefs
35 from Noyau.N_CR import CR
36 from Editeur.utils  import init_rep_cata_dev
37
38 from Editeur    import analyse_catalogue
39 from Editeur    import autre_analyse_cata
40 from Editeur    import uiinfo
41 from monChoixCata import MonChoixCata
42
43 from PyQt4 import *
44 from PyQt4.QtGui import *
45 from PyQt4.QtCore import *
46
47 version="14"
48
49 class READERCATA:
50
51    def __init__(self,QWParent, appliEficas):
52       self.QWParent=QWParent
53       self.appliEficas=self.QWParent.appliEficas
54       self.code=self.QWParent.code
55       self.QWParent.format_fichier='python'
56       self.version_code=self.QWParent.version_code
57       self.version_cata=None
58       self.fic_cata=None
59       self.OpenCata()
60       self.cataitem=None
61
62    def OpenCata(self):
63       """ 
64           Ouvre le catalogue standard du code courant, cad le catalogue présent
65           dans le répertoire Cata 
66       """
67       message1 = "Compilation des fichiers Eficas \n\n Veuillez patienter ..."
68
69       liste_cata_possibles=[]
70       for catalogue in self.appliEficas.CONFIGURATION.catalogues:
71           if catalogue[0] == self.code :
72              liste_cata_possibles.append(catalogue)
73
74       if len(liste_cata_possibles)==0:          
75           QMessageBox.critical( self.QWParent, "Import du catalogue","Pas de catalogue defini pour le code %s" % self.code)
76           self.appliEficas.close()
77           sys.exit(1)
78
79       if self.version_code is not None:
80           # La version a ete fixee
81           for cata in liste_cata_possibles:
82              if self.version_code == cata[1]:
83                 self.fic_cata = cata[2]
84                 self.appliEficas.format_fichier=cata[3]
85       elif len(liste_cata_possibles)==1:
86           self.fic_cata = liste_cata_possibles[0][2]
87           self.version_code = liste_cata_possibles[0][1]
88           self.QWParent.format_fichier=liste_cata_possibles[0][3] 
89           lab=QString("Eficas V1.") 
90           lab+=QString(version) 
91           lab+=QString(" pour ")
92           lab+=QString(self.code) 
93           lab+=QString(" avec le catalogue ")
94           lab+=self.version_code
95           try :
96           # souci pour les includes
97               self.appliEficas.setWindowTitle(lab)
98           except :
99               pass
100       else:
101           # plusieurs catalogues sont disponibles : il faut demander a l'utilisateur
102           # lequel il veut utiliser ...
103           self.ask_choix_catalogue()
104
105       if self.fic_cata == None :
106           print "Pas de catalogue pour code %s, version %s" %(self.code,self.version_code)
107           sys.exit(0)
108
109       self.determineMater()
110
111
112       # détermination de fic_cata_c et fic_cata_p
113       self.fic_cata_c = self.fic_cata + 'c'
114       self.fic_cata_p = os.path.splitext(self.fic_cata)[0]+'_pickled.py'
115
116       # import du catalogue
117       self.cata = self.import_cata(self.fic_cata)
118       if not self.cata :          
119           QMessageBox.critical( self.QWParent, "Import du catalogue","Impossible d'importer le catalogue %s" %self.fic_cata)
120           self.appliEficas.close()
121           sys.exit(1)
122       #
123       # analyse du catalogue (ordre des mots-clés)
124       #
125       # Retrouve_Ordre_Cata_Standard fait une analyse textuelle du catalogue
126       # remplacé par Retrouve_Ordre_Cata_Standard_autre qui utilise une numerotation
127       # des mots clés a la création
128       self.Retrouve_Ordre_Cata_Standard_autre()
129
130       #
131       # analyse des données liées a  l'IHM : UIinfo
132       #
133       uiinfo.traite_UIinfo(self.cata)
134
135       #
136       # traitement des clefs documentaires
137       #
138       self.traite_clefs_documentaires()
139
140       # chargement et analyse des catalogues développeur (le cas échéant)
141       #
142       if self.appliEficas.CONFIGURATION.isdeveloppeur == 'OUI' :
143           init_rep_cata_dev(self.fic_cata,self.appliEficas.CONFIGURATION.path_cata_dev)
144           fic_cata_dev = os.path.join(self.appliEficas.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
145           if os.path.isfile(fic_cata_dev):
146               # il y a bien un catalogue développeur : il faut récupérer le module_object associé ...
147               test = self.compile_cata(fic_cata_dev,fic_cata_dev+'c')
148               if not test :
149                   showinfo("Compilation catalogue développeur",
150                            "Erreur dans la compilation du catalogue développeur")
151                   self.cata = (self.cata,)
152               else:
153                   self.cata_dev =self.import_cata(fic_cata_dev)
154                   #self.Retrouve_Ordre_Cata_Developpeur()
155                   self.Retrouve_Ordre_Cata_Developpeur_autre()
156                   self.cata = (self.cata,self.cata_dev)
157           else:
158               self.cata = (self.cata,)
159       else:
160           self.cata = (self.cata,)
161       titre="Eficas V1.14 avec le catalogue " + os.path.basename(self.fic_cata)
162       if self.appliEficas.top:
163         self.appliEficas.setWindowTitle(titre)
164       self.appliEficas.titre=titre
165
166    def determineMater(self) :
167       # Determinination du repertoire materiau
168       v_codeSansPoint=self.version_code
169       v_codeSansPoint=re.sub("\.","",v_codeSansPoint)
170       chaine="rep_mat_"+v_codeSansPoint
171       if hasattr(self.appliEficas.CONFIGURATION,chaine):
172           a=getattr(self.appliEficas.CONFIGURATION,chaine)
173       else :
174           try :
175              a=self.appliEficas.CONFIGURATION.dRepMat[self.version_code]
176           except :
177              if self.code == "ASTER" :
178                 print "Probleme avec le repertoire materiau"
179              a='.'
180       self.appliEficas.CONFIGURATION.rep_mat=a
181
182    def import_cata(self,cata):
183       """ 
184           Réalise l'import du catalogue dont le chemin d'acca¨s est donné par cata
185       """
186       nom_cata = os.path.splitext(os.path.basename(cata))[0]
187       rep_cata = os.path.dirname(cata)
188       sys.path[:0] = [rep_cata]
189       try :
190           o=__import__(nom_cata)
191           return o
192       except Exception,e:
193           traceback.print_exc()
194           return 0
195
196    def Retrouve_Ordre_Cata_Standard_autre(self):
197       """ 
198           Construit une structure de données dans le catalogue qui permet
199           a  EFICAS de retrouver l'ordre des mots-clés dans le texte du catalogue.
200           Pour chaque entité du catlogue on crée une liste de nom ordre_mc qui
201           contient le nom des mots clés dans le bon ordre
202       """ 
203       self.cata_ordonne_dico,self.appliEficas.liste_simp_reel=autre_analyse_cata.analyse_catalogue(self.cata)
204
205    def Retrouve_Ordre_Cata_Standard(self):
206       """ 
207           Retrouve l'ordre des mots-clés dans le catalogue, cad :
208            - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
209                l'ordre des mots-clés dans le catalogue
210            - s'il n'a pas été modifié, relie le fichier pickle 
211       """
212       time1 = os.path.getmtime(self.fic_cata)
213       try :
214           time2 = os.path.getmtime(self.fic_cata_p)
215       except:
216           time2 = 0
217       if time2 > time1 :
218           # l'objet catalogue n'a pas été modifié depuis le dernier "pickle"
219           self.Get_Ordre_Cata()
220       else :
221           # le catalogue a été modifié depuis le dernier "pickle" :
222           # il faut retrouver l'ordre du catalogue et refaire pickle
223           self.Get_Ordre_Cata(mode='cata')
224       self.appliEficas.affiche_infos("Catalogue standard chargé")
225
226    def Retrouve_Ordre_Cata_Developpeur(self):
227       """ 
228           Retrouve l'ordre des mots-clés dans le catalogue, cad :
229           - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
230             l'ordre des mots-clés dans le catalogue
231           - s'il n'a pas été modifié, relie le fichier pickle 
232       """
233       if self.code != 'ASTER' : return
234       fic_cata = os.path.join(self.appliEficas.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
235       message="Chargement catalogue développeur présent dans :\n %s..." % self.appliEficas.CONFIGURATION.path_cata_dev
236       cata_dev_ordonne = analyse_cata.analyse_catalogue(self,self.fic_cata)
237       self.cata_dev_ordonne_cr = cata_dev_ordonne.cr
238       cata_dev_ordonne_dico = cata_dev_ordonne.entites
239       self.cata_ordonne_dico.update(cata_dev_ordonne_dico)
240       self.appliEficas.affiche_infos(" catalogue(s) développeur(s) chargé(s)" )
241
242    def Retrouve_Ordre_Cata_Developpeur_autre(self):
243       """
244           Retrouve l'ordre des mots-clés dans le catalogue, cad :
245           - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
246             l'ordre des mots-clés dans le catalogue
247           - s'il n'a pas été modifié, relie le fichier pickle
248       """
249       if self.code != 'ASTER' : return
250       message="Chargement catalogue développeur présent dans :\n %s..." % self.appliEficas.CONFIGURATION.path_cata_dev
251       cata_dev_ordonne_dico,self.appliEficas.liste_simp_reel=autre_analyse_cata.analyse_catalogue(self.cata)
252       self.cata_ordonne_dico.update(cata_dev_ordonne_dico)
253       self.appliEficas.affiche_infos(" catalogue(s) développeur(s) chargé(s)" )
254
255    def Get_Ordre_Cata(self,mode='pickle'):
256       """ 
257           Retrouve l'ordre du catalogue :
258             - mode='pickle ': tente de relire le fichier pickle et sinon lance l'analyse du catalogue
259             - mode='cata'   : force l'analyse du catalogue directement sans relire le pickle
260       """
261       if mode == 'pickle' :
262           try:
263               f = open(self.fic_cata_p)
264               u = cPickle.Unpickler(f)
265               self.cata_ordonne_dico = u.load()
266               f.close()
267           except :
268               # on peut ne pas arriver a  relire le fichier pickle s'il a été altéré
269               # ou (le plus probable) s'il a été créé sous un autre OS
270               self.Get_Ordre_Cata(mode='cata')
271       elif mode == 'cata':
272           cata_ordonne = analyse_catalogue.analyse_catalogue(self,self.fic_cata)
273           self.cata_ordonne_cr = cata_ordonne.cr
274           self.cata_ordonne_dico = cata_ordonne.entites
275           f = open(self.fic_cata_p,'w+')
276           p = cPickle.Pickler(f)
277           p.dump(self.cata_ordonne_dico)
278           f.close()
279       else :
280           raise Exception("Appel a  un mode inconnu de Get_Ordre_Cata : %s" % mode)
281           return
282
283    def ask_choix_catalogue(self):
284       """
285       Ouvre une fenetre de sélection du catalogue dans le cas oa¹ plusieurs
286       ont été définis dans Accas/editeur.ini
287       """      
288       # construction du dictionnaire et de la liste des catalogues
289       self.dico_catalogues = {}
290       defaut = None
291       for catalogue in self.appliEficas.CONFIGURATION.catalogues:
292           if catalogue[0] == self.code :
293               self.dico_catalogues[catalogue[1]] = catalogue
294               if len(catalogue) == 5 :
295                   if catalogue[4]=='defaut' : defaut = catalogue[1]
296       liste_choix = self.dico_catalogues.keys()
297       liste_choix.sort()
298
299       lab=QString("Eficas V1.") 
300       lab+=QString(version) 
301       lab+=QString(" pour ")
302       lab+=QString(self.code) 
303       lab+=QString(" avec le catalogue ")
304
305       # teste si plusieurs catalogues ou non
306       if len(liste_choix) == 0:          
307           QMessageBox.critical( self.QWParent, "", "Aucun catalogue déclaré pour %s" %self.code)
308           self.appliEficas.close()
309           sys.exit(1)
310           
311       # création d'une boite de dialogue modale
312       widgetChoix=MonChoixCata(liste_choix,self, self.appliEficas, "", True )
313       ret=widgetChoix.exec_()
314       
315       lab=QString("Eficas V1.") 
316       lab+=QString(version) 
317       lab+=QString(" pour ")
318       lab+=QString(self.code) 
319       lab+=QString(" avec le catalogue ")
320       if ret == QDialog.Accepted:
321           self.version_cata=str(self.version_cata)
322           self.fic_cata = self.dico_catalogues[self.version_cata][2]
323           self.version_code = self.version_cata
324           self.appliEficas.format_fichier = self.dico_catalogues[self.version_cata][3]
325           lab+=self.version_cata
326           self.appliEficas.setWindowTitle(lab)
327           #qApp.mainWidget().setCaption(lab)
328       else :
329           sys.exit(0)
330
331
332    def compile_cata(self,cata,catac):
333       """ 
334            Teste si le catalogue a bien besoin d'etre recompilé et si oui, le compile et
335            affiche un message dans le splash . Retourne 1 si la compilation s'est bien déroulée,
336            0 sinon.
337       """
338       time1 = os.path.getmtime(cata)
339       try:
340           time2 = os.path.getmtime(catac)
341       except:
342           time2 = 0
343       if time1 > time2:
344           try:
345               # le catalogue doit etre recompilé avant d'etre importé
346               if self.QWParent.test == 0 :
347                  splash._splash.configure(text="Compilation du catalogue\nCela peut prendre plusieurs secondes ...")
348               py_compile.compile(cata)
349           except:
350               return 0
351       return 1
352
353
354
355    def visuCRCATA(self):
356       """
357       Méthode permettant l'affichage du rapport de validation
358       """
359       cr = CR( debut = "Début rapport de validation du catalogue",
360                fin = "Fin rapport de validation du catalogue")
361       titre="rapport de validation du catalogue"
362       if hasattr(self,'cata_ordonne_cr') :
363           cr.add(self.cata_ordonne_cr)
364       if hasattr(self,'cata_dev_ordonne_cr') :
365           cr.add(self.cata_dev_ordonne_cr)
366       for cata in self.cata:
367           if hasattr(cata,'JdC'):
368               cr.add(cata.JdC.report())
369       texte_cr = str(cr)
370       self.visu_texte_cr = Fenetre(self.appliEficas,titre=titre,texte=texte_cr)
371
372
373    def traite_clefs_documentaires(self):
374       try:
375         self.fic_cata_clef=os.path.splitext(self.fic_cata_c)[0]+'_clefs_docu'
376         f=open(self.fic_cata_clef)
377       except:
378         #print "Pas de fichier associé contenant des clefs documentaires"
379         return
380
381       dict_clef_docu={}
382       for l in f.readlines():
383           clef=l.split(':')[0]
384           docu=l.split(':')[1]
385           docu=docu[0:-1]
386           dict_clef_docu[clef]=docu
387       for oper in self.cata.JdC.commandes:
388            if dict_clef_docu.has_key(oper.nom):
389               oper.docu=dict_clef_docu[oper.nom]