Salome HOME
Update version
[tools/eficas.git] / InterfaceQT4 / readercata.py
1 # -*-  coding: utf-8 -*-
2 # Copyright (C) 2007-2021   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 """
21     Ce module sert a lire un catalogue et a construire
22     un objet CataItem pour Eficas.
23     Il s'appuie sur la classe READERCATA
24 """
25 # Modules Python
26 from __future__ import absolute_import
27 from __future__ import print_function
28 try :
29     from builtins import str
30     from builtins import object
31 except : pass
32 import os, sys
33
34 # Modules Eficas
35 from Noyau.N_CR import CR
36 from Editeur.catadesc import CatalogDescription
37
38 import analyse_catalogue
39 import analyse_catalogue_initial
40 import autre_analyse_cata
41 import uiinfo
42 from Extensions.i18n import tr
43 from Extensions.eficas_exception import EficasException
44
45
46 #-------------------------------
47 class ReaderCataCommun(object):
48 #-------------------------------
49
50     def askChoixCatalogue(self, cataListeChoix):
51     # ____________________________________________
52         """
53         Ouvre une fenetre de selection du catalogue dans le cas où plusieurs
54         ont ete definis dans Accas/editeur.ini
55         """
56         try :
57             from PyQt5.QtWidgets import QDialog
58         except :
59             print ('Pas de choix interactif sans qt')
60             return
61
62         code = getattr(self.appliEficas.maConfiguration, "code", None)
63         if code != None :
64             title=tr("Choix d une version du code ")+str(code)
65         else :
66             title=tr("Choix d une version ")
67
68         from InterfaceQT4.monChoixCata import MonChoixCata
69         widgetChoix = MonChoixCata(self.appliEficas, [cata.labelCode for cata in cataListeChoix], title)
70         ret=widgetChoix.exec_()
71
72
73         lab=str(self.VERSION_EFICAS)+" "
74         lab+=tr(" pour ")
75         lab+=str(self.code)
76         lab+=tr(" avec le catalogue ")
77         if ret == QDialog.Accepted:
78             cata = cataListeChoix[widgetChoix.CBChoixCata.currentIndex()]
79             self.fichierCata = cata.fichierCata
80             self.labelCode   = cata.labelCode
81             self.appliEficas.formatFichierOut = cata.formatFichierOut
82             self.appliEficas.formatFichierIn  = cata.formatFichierIn
83             lab+=self.labelCode
84             self.appliEficas.setWindowTitle(lab)
85             widgetChoix.close()
86         else:
87             widgetChoix.close()
88             raise EficasException()
89
90     def choisitCata(self):
91     # ____________________
92
93
94         listeCataPossibles=[]
95         self.Commandes_Ordre_Catalogue=[]
96
97
98         listeTousLesCatas = []
99         for catalogue in self.appliEficas.maConfiguration.catalogues:
100             if isinstance(catalogue, CatalogDescription): listeTousLesCatas.append(catalogue)
101             elif isinstance(catalogue, tuple)           : listeTousLesCatas.append(CatalogDescription.createFromTuple(catalogue))
102             else: print(("Catalog description cannot be interpreted: ", catalogue))
103
104         if self.labelCode is  None: listeCataPossibles = listeTousLesCatas
105         else :
106             for catalogue in listeTousLesCatas:
107                 if catalogue.code == self.code and catalogue.ssCode == self.ssCode:
108                     listeCataPossibles.append(catalogue)
109
110         if len(listeCataPossibles)==0:
111             try :
112                 QMessageBox.critical(self.QWParent, tr("Import du catalogue"),
113                                 tr("Pas de catalogue defini pour le code ") + self.code)
114             except :
115                 print("Pas de catalogue defini pour le code " + self.code)
116             if self.appliEficas.salome == 0 : sys.exit(1)
117             self.appliEficas.close()
118             return
119
120         if self.labelCode is not None:
121             # La version a ete fixee
122             for cata in listeCataPossibles:
123                 if self.labelCode == cata.labelCode:
124                     self.fichierCata = cata.fichierCata
125                     self.labelCode   = cata.labelCode
126                     self.appliEficas.formatFichierOut = cata.formatFichierOut
127                     self.appliEficas.formatFichierIn  = cata.formatFichierIn
128         else:
129             cataChoiceList = []
130             for cata in listeCataPossibles:
131                 if cata.selectable:
132                     if cata.default : cataChoiceList.insert(0, cata)
133                     else            : cataChoiceList.append(cata)
134
135         # le catalogue est fixe dans la ligne de commande
136         if self.appliEficas.fichierCata != None :
137             trouve=False
138             for catalogue in listeTousLesCatas:
139                 if os.path.abspath(catalogue.fichierCata) ==  (os.path.abspath(self.appliEficas.fichierCata)) :
140                     listeCataPossibles=(catalogue,)
141                     trouve=True
142                     break
143             if not trouve:
144                 catalogue=CatalogDescription.createFromTuple((self.code ,self.code,self.appliEficas.fichierCata,'python','python'))
145                 listeCataPossibles=(catalogue,)
146
147
148         if len(listeCataPossibles)==0:
149             try :
150                 from PyQt5.QtWidgets import QMessageBox, QDialog
151                 QMessageBox.critical(self.QWParent, tr("Import du catalogue"),
152                                   tr("Pas de catalogue defini pour le code ") + self.code)
153             except :
154                 print ("Pas de catalogue defini pour le code " + self.code)
155             self.appliEficas.close()
156             if self.appliEficas.salome == 0 : sys.exit(1)
157             return
158
159
160         # le label est fixe dans la ligne de commande
161         if self.labelCode is not None:
162             # La version a ete fixee
163             for cata in listeCataPossibles:
164                 if self.labelCode == cata.labelCode:
165                     self.fichierCata = cata.fichierCata
166                     self.appliEficas.formatFichierIn  = cata.formatFichierIn
167                     self.appliEficas.formatFichierOut = cata.formatFichierOut
168         else:
169             cataListeChoix = []
170             for cata in listeCataPossibles:
171                 if cata.default : cataListeChoix.insert(0, cata)
172                 else            : cataListeChoix.append(cata)
173
174             if len(cataListeChoix) == 0:
175                 try :
176                     from PyQt5.QtWidgets import QMessageBox
177                     QMessageBox.critical(self.QWParent, tr("Import du catalogue"),
178                                        tr("Aucun catalogue trouve"))
179                 except :
180                     print ("Pas de catalogue defini pour le code " + self.code)
181                 self.appliEficas.close()
182                 if self.appliEficas.salome == 0 : sys.exit(1)
183
184             elif len(cataListeChoix) == 1:
185                 self.fichierCata = cataListeChoix[0].fichierCata
186                 self.labelCode   = cataListeChoix[0].labelCode
187                 self.appliEficas.formatFichierOut = cataListeChoix[0].formatFichierOut
188                 self.appliEficas.formatFichierIn  = cataListeChoix[0].formatFichierIn
189
190             else:
191                 # plusieurs catalogues sont disponibles : il faut demander a l'utilisateur
192                 # lequel il veut utiliser ...
193                 if self.appliEficas.ssIhm :
194                     print ('Unable to know which catafile is choosen')
195                     exit()
196                 self.askChoixCatalogue(cataListeChoix)
197                 self.demandeCatalogue=True
198
199         if self.fichierCata == None :
200             if self.appliEficas.salome == 0 :
201                 print(("Pas de catalogue pour code %s, version %s" %(self.code,self.labelCode)))
202                 sys.exit(1)
203             else :
204                 self.appliEficas.close()
205                 return
206
207
208 #------------------------------------
209 class ReaderCata (ReaderCataCommun):
210 #------------------------------------
211
212     def __init__(self,QWParent, appliEficas):
213     # _______________________________________
214
215
216         self.QWParent=QWParent
217         self.appliEficas=self.QWParent.appliEficas
218         self.VERSION_EFICAS=self.appliEficas.VERSION_EFICAS
219         self.demandeCatalogue=False
220         self.code=self.appliEficas.code
221         self.ssCode=self.appliEficas.ssCode
222         # on positionne par defaut mais est-ce vraiment necessaire
223         self.appliEficas.formatFichierIn='python'
224         self.appliEficas.formatFichierOut='python'
225         self.labelCode=self.appliEficas.labelCode
226         self.fichierCata=self.appliEficas.fichierCata
227         self.openCata()
228         self.traiteIcones()
229         self.cataitem=None
230         self.creeDicoInverse()
231         if self.code=="TELEMAC": self.creeDicoCasToCata()
232
233
234     def openCata(self):
235         """
236             Ouvre le catalogue standard du code courant, cad le catalogue present
237             dans le repertoire Cata
238         """
239         # import du catalogue
240         if self.fichierCata == None : self.choisitCata()
241
242         self.cata = self.importCata(self.fichierCata)
243         if self.code == 'NonConnu' : self.code = self.cata.JdC.code
244         modeleMetier = None
245         dicoEltDif = {}
246         if not (self.appliEficas.genereXSD) :
247             if (self.appliEficas.maConfiguration.withXSD or self.appliEficas.withXSD)  :
248                 try :
249                     import pyxb
250                 except :
251                     self.QWParent.informe('environnement', 'please source pyxb environment')
252                     exit()
253                 try :
254                     nomCataXsd = os.path.splitext(os.path.basename(self.fichierCata))[0]
255                     fichierCataTrunc=os.path.splitext(os.path.basename(self.fichierCata))[0]
256                     nomCataXsd = fichierCataTrunc+'_driver'
257                     pathCata = os.path.dirname(self.fichierCata)+'/raw/'+nomCataXsd+'.py'
258                     import imp
259                     modeleMetier= imp.load_source(nomCataXsd,pathCata)
260                     #print ('nomCataXsd , pathCata ',nomCataXsd,pathCata)
261                     try :
262                     #if 1 :
263                         #monObjetAnnotation = getattr(modeleMetier,'PNEFdico_'+self.code)
264                         monObjetAnnotation = getattr(modeleMetier,'PNEFdico')
265                         texte=monObjetAnnotation.__doc__
266                     except :
267                         texte=None
268                     if texte != None and texte != "":
269                         l={}
270                         texte='dicoEltDif = '+ texte
271                         exec (texte, globals(),l)
272                         dicoEltDif=l['dicoEltDif']
273                     #print ('dans readerCata _________', dicoEltDif)
274
275                 except :
276                     if self.appliEficas.ssIhm == False :print ('______________ poum import cata_genere ')
277                     self.QWParent.informe('XSD driver', 'unable to load xsd driver',critique=False)
278                     modeleMetier = None
279
280         self.cata.DicoNomTypeDifferentNomElt=dicoEltDif
281
282         if hasattr(self.cata, 'implement'): self.cata.JdC.implement = self.cata.implement
283         else : self.cata.JdC.implement = ""
284         if hasattr(self.cata, 'importedBy'): self.cata.JdC.importedBy = self.cata.importedBy
285         else : self.cata.JdC.importedBy = []
286         self.cata.JdC.labelCode = self.labelCode
287         if not(hasattr(self.cata, 'dict_condition')): self.cata.dict_condition = {}
288
289         # pointeur pour le dumpXSD
290         self.cata.JdC.cata=self.cata
291
292         self.cata.modeleMetier = modeleMetier
293         if not self.cata :
294             #try:
295               #from PyQt5.QtWidgets import QMessageBox, QDialog
296               #QMessageBox.critical( self.QWParent, tr("Import du catalogue"),tr("Impossible d'importer le catalogue ")+ self.fichierCata)
297             #except :
298             #  print ("Impossible d'importer le catalogue "+ self.fichierCata)
299             self.QWParent.informe("Catalogue","Impossible d'importer le catalogue "+ self.fichierCata)
300             self.appliEficas.close()
301             if self.appliEficas.salome == 0 :
302                 sys.exit(1)
303         #
304         # analyse du catalogue (ordre des mots-cles)
305         #
306         # retrouveOrdreCataStandard fait une analyse textuelle du catalogue
307         # remplace par retrouveOrdreCataStandardAutre qui utilise une numerotation
308         # des mots cles a la creation
309         #print (dir(self.cata))
310         self.retrouveOrdreCataStandardAutre()
311         if self.appliEficas.maConfiguration.modeNouvCommande == "initial" : self.retrouveOrdreCataStandard()
312         if hasattr(self.cata, 'Ordre_Des_Commandes') : self.Ordre_Des_Commandes=self.cata.Ordre_Des_Commandes
313         else : self.Ordre_Des_Commandes=None
314
315         if hasattr(self.cata, 'Classement_Commandes_Ds_Arbre') :
316             self.Classement_Commandes_Ds_Arbre=self.cata.Classement_Commandes_Ds_Arbre
317         else : self.Classement_Commandes_Ds_Arbre=()
318         if hasattr(self.cata,'enum'):
319             try :
320                 _temp= __import__(self.cata.enum,globals(), locals(), ['DicoEnumCasFrToEnumCasEn', 'TelemacdicoEn'], 0)
321                 self.DicoEnumCasFrToEnumCasEn = _temp.DicoEnumCasFrToEnumCasEn
322                 self.TelemacdicoEn = _temp.TelemacdicoEn
323             except : pass
324
325         #print self.cata.Ordre_Des_Commandes
326
327         #
328         # analyse des donnees liees l'IHM : UIinfo
329         #
330         uiinfo.traite_UIinfo(self.cata)
331
332         #
333         # traitement des clefs documentaires
334         #
335
336         self.titre=self.VERSION_EFICAS+" "+tr( " avec le catalogue ") + os.path.basename(self.fichierCata)
337         if self.appliEficas.ssIhm == False : self.appliEficas.setWindowTitle(self.titre)
338         self.appliEficas.titre=self.titre
339         self.QWParent.titre=self.titre
340
341
342     def importCata(self,cata):
343         """
344             Realise l'import du catalogue dont le chemin d'acces est donne par cata
345         """
346         nom_cata = os.path.splitext(os.path.basename(cata))[0]
347         rep_cata = os.path.dirname(cata)
348         sys.path[:0] = [rep_cata]
349         self.appliEficas.listeAEnlever.append(rep_cata)
350
351         # PNPNPN pas propre __ A reflechir
352         if 'cata_Vimmp' in list(sys.modules.keys()) :
353             del sys.modules['cata_Vimmp']
354
355         if nom_cata in list(sys.modules.keys()) :
356             del sys.modules[nom_cata]
357
358         for k in sys.modules:
359             if k[0:len(nom_cata)+1] == nom_cata+'.':
360                 del sys.modules[k]
361
362         mesScriptsNomFichier='mesScripts_'+self.code.upper()
363         try :
364             self.appliEficas.mesScripts[self.code]=__import__(mesScriptsNomFichier)
365         except:
366             pass
367
368         #if 1 :
369         try :
370             o=__import__(nom_cata)
371             return o
372         except Exception as e:
373             self.QWParent.informe('catalog', 'unable to load catalog file')
374             import traceback
375             traceback.print_exc()
376             return 0
377
378
379
380     def retrouveOrdreCataStandardAutre(self):
381         """
382             Construit une structure de donnees dans le catalogue qui permet
383             a EFICAS de retrouver l'ordre des mots-cles dans le texte du catalogue.
384             Pour chaque entite du catlogue on cree une liste de nom ordre_mc qui
385             contient le nom des mots cles dans le bon ordre
386         """
387         self.cata_ordonne_dico, self.appliEficas.liste_simp_reel=autre_analyse_cata.analyseCatalogue(self.cata)
388         #print ('_________________________________________', self)
389         #print (self.cata_ordonne_dico)
390         #self.appliEficas.liste_simp_reel = ()
391         #self.cata_ordonne_dico = {}
392
393     def retrouveOrdreCataStandard(self):
394         """
395             Retrouve l'ordre des mots-cles dans le catalogue, cad :
396             Attention s appuie sur les commentaires
397         """
398         nom_cata = os.path.splitext(os.path.basename(self.fichierCata))[0]
399         rep_cata = os.path.dirname(self.fichierCata)
400         self.Commandes_Ordre_Catalogue = analyse_catalogue_initial.analyseCatalogue(self.fichierCata)
401         #print self.Commandes_Ordre_Catalogue
402
403     def traiteIcones(self):
404         if self.appliEficas.maConfiguration.ficIcones==None : return
405         try:
406             ficIcones=self.appliEficas.maConfiguration.ficIcones
407             fichierIcones = __import__(ficIcones, globals(), locals(), [], 0)
408             self.appliEficas.maConfiguration.dicoIcones=fichierIcones.dicoDesIcones.dicoIcones
409             self.appliEficas.maConfiguration.dicoImages=fichierIcones.dicoDesIcones.dicoImages
410         except:
411             print ("Pas de fichier associe contenant des liens sur les icones ")
412             self.appliEficas.maConfiguration.dicoIcones={}
413
414
415
416     def creeDicoInverse(self):
417         self.dicoInverse={}
418         self.dicoMC={}
419         listeEtapes=self.cata.JdC.commandes
420         for e in self.cata.JdC.commandes:
421             self.traiteEntite(e)
422
423
424     def creeDicoCasToCata(self):
425         if hasattr(self.cata,'dicoCasEn'):
426             _temp= __import__(self.cata.dicoCasEn,globals(), locals(), ['DicoCasEnToCata'], 0)
427             if self.appliEficas.langue=="ang" :
428                 self.dicoCasToCata=_temp.dicoCasEnToCata
429             else :
430                 self.dicoCasToCata=_temp.dicoCasFrToCata
431
432
433
434     def traiteEntite(self,e):
435         boolIn=0
436         for (nomFils, fils) in list(e.entites.items()) :
437             self.dicoMC[nomFils]=fils
438             self.traiteEntite(fils)
439             boolIn=1
440         if boolIn==0 :
441             liste=[]
442             moi=e
443             while hasattr(moi,'pere') :
444                 liste.append((moi.nom,moi))
445                 moi=moi.pere
446             liste.append((moi.nom,moi))
447             self.dicoInverse[e.nom]=liste
448             self.dicoInverse[tr(e.nom)]=liste
449
450     def creeRubrique(self,e,dico, niveau):
451         from Accas import A_BLOC
452         decale=niveau*"   "
453         #if niveau != 0 :
454         #    if isinstance(e,A_BLOC.BLOC): print decale, e.condition
455         #    else :                           print decale, e. nom
456         for (nom, fils) in list(e.entites.items()) :
457             if  list(fils.entites.items()) != [] : self.creeRubrique(fils,dico,niveau+1)
458             #else : print (niveau+1)*"   ", nom
459
460
461     #def dumpToXsdEficas(self):
462         # Pas sur qu on ait jamais besoin de cela
463     #    pass
464         #from Efi2Xsd import readerEfficas
465         #newSchema=   xml = open('Cata_MED_FAM.xml').read()
466         #SchemaMed = efficas.CreateFromDocument(xml)
467         #SchemaMed.alimenteCata(self.cata)