Salome HOME
bug sur un mesage dans une exception sur un validator (cf JPA)
[tools/eficas.git] / InterfaceQT4 / editor.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 from __future__ import absolute_import
21 from __future__ import print_function
22 try :
23     from builtins import str
24     from builtins import range
25 except : pass
26
27 import types,sys,os, re
28 import  subprocess
29 import traceback
30
31
32 from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog, QApplication, QSplitter, QLabel
33 from PyQt5.QtGui     import QPalette
34 from PyQt5.QtCore    import QProcess, QFileInfo, QTimer, Qt, QDir, QSize
35
36 import traceback
37
38 # Modules Eficas
39 from Extensions.i18n import tr
40
41 from Editeur        import session
42 from Editeur        import comploader
43 from Editeur        import Objecttreeitem
44 from InterfaceQT4   import browser
45
46 from desBaseWidget    import Ui_baseWidget
47 from InterfaceQT4.monViewTexte   import ViewText
48 from monWidgetCreeParam import MonWidgetCreeParam
49
50 DictExtensions= {"MAP" : ".map", "TELEMAC" : '.cas'}
51 debug = False
52
53
54 from InterfaceQT4.editorSsIhm    import JDCEditorSsIhm
55
56
57 class JDCEditor(JDCEditorSsIhm,Ui_baseWidget,QWidget):
58 # ----------------------------------------- #
59     """
60        Editeur de jdc
61     """
62
63 # ----------------------------------------
64 # Methodes faisant appel a ssIhm
65 # ----------------------------------------
66
67     def __init__ (self,appliEficas,fichier = None, jdc=None, QWParent=None, units = None, include=0):
68     #------------------------------------------------------------------------------------------------
69
70
71         QWidget.__init__(self,None)
72         self.setupUi(self)
73
74         self.inhibeSplitter=0
75         self.widgetOptionnel=None
76         self.fenetreCentraleAffichee=None
77         self.dejaDansPlieTout=False
78         self.listeDesListesOuvertes=set()
79         if appliEficas!=None and hasattr(appliEficas,"statusBar"): self.sb = appliEficas.statusBar()
80         else : self.sb = None
81         self.QWParent=QWParent
82
83         JDCEditorSsIhm. __init__ (self,appliEficas,fichier, jdc,units,include)
84         if self.jdc:
85             comploader.chargerComposants()
86             self.jdc_item=Objecttreeitem.makeObjecttreeitem( self, "nom", self.jdc )
87
88
89         # Particularites IHM : met la fenetre a jour
90
91         self.initSplitterSizes()
92
93         #self.affiche=self.appliEficas.maConfiguration.affiche
94
95         self.afficheListesPliees=self.maConfiguration.afficheListesPliees
96         if self.code in ['MAP','CARMELCND','PSEN'] : self.maConfiguration.afficheCommandesPliees=False
97         if self.code in ['MAP',]: self.fermeArbre()
98         #   self.widgetTree.close()
99         #   self.widgetTree=None
100
101         if self.maConfiguration.closeArbre      : self.fermeArbre()
102         if self.maConfiguration.closeOptionnel  : self.fermeOptionnel()
103         if self.maConfiguration.boutonDsMenuBar : self.appliEficas.remplitIconesCommandes()
104
105
106         self.formatFichierOut =  self.appliEficas.formatFichierOut
107         self.formatFichierIn  =  self.appliEficas.formatFichierIn
108
109         self.node_selected = []
110         self.deplier = True
111         self.message=''
112         self.afficheApresInsert=False
113         if self.maConfiguration.closeArbre    : self.afficheApresInsert=True
114         if self.code in ['Adao','ADAO','MAP'] : self.afficheApresInsert=True
115         if self.code in ['TELEMAC',]          : self.enteteQTree='premier'
116         else                                  : self.enteteQTree='complet'
117         if self.code in ['Adao','ADAO','TELEMAC','VP'] : self.affichePlie=True
118         else                                      : self.affichePlie=False
119
120         self.Commandes_Ordre_Catalogue =self.readercata.Commandes_Ordre_Catalogue
121
122         if self.appliEficas.readercata.demandeCatalogue==True  :
123             nomFichierTranslation='translatorFichier'+'_'+str(self.appliEficas.readercata.labelCode)
124             if hasattr(self.appliEficas.maConfiguration,nomFichierTranslation) :
125                 translatorFichier=getattr(self.appliEficas.maConfiguration,nomFichierTranslation)
126                 from Extensions import localisation
127                 localisation.localise(None,self.appliEficas.langue,translatorFichier=translatorFichier)
128
129
130         if self.jdc_item and self.appliEficas.ssIhm==False :
131             self.tree = browser.JDCTree( self.jdc_item,  self )
132         self.appliEficas.construitMenu()
133
134         self.adjustSize()
135
136
137     #-------------------------------#
138     def readFile(self, fn):
139     #--------------------------------#
140         """
141         Public slot to read the text from a file.
142         @param fn filename to read from (string or QString)
143         """
144
145         jdc=JDCEditorSsIhm.readFile(self, fn)
146
147         # Particularites IHM : met le titre de la fenetre a jour
148 #        qApp.restoreOverrideCursor()
149         if self.fileInfo!= None : self.lastModified = self.fileInfo.lastModified()
150         nouveauTitre=self.titre+"              "+os.path.basename(self.fichier)
151         self.appliEficas.setWindowTitle(nouveauTitre)
152
153         return jdc
154
155 # ---------------------------------------------
156 # Methodes Inchangees
157 # ---------------------------------------------
158 #   _newJDC
159 #   _newJDCInclude
160 #   __generateTempFilename
161 #   getSource
162 #   generDico
163 #   viewJdcSource
164 #   viewJdcPy
165 #   viewJdcRapport
166 #   getFileName
167 #   initModif
168 #   writeFile
169 #   getTextJDC
170 #   verifieChecksum
171 #   getChecksum
172 #   getDico
173 #   chercheGroupes
174 #   chercheDico
175 #   saveFileLegerAs
176
177 # ---------------------------------------------
178 # Methodes Surchargees
179 # ---------------------------------------------
180
181     #-----------------------------------------------------------------------#
182     def _viewText(self, txt, caption = "FILE_VIEWER",largeur=1200,hauteur=600):
183     #--------------------------------------------------------------------#
184         w = ViewText( self.QWParent,self ,caption,txt,largeur,hauteur)
185         w.show()
186
187     #--------------------------------#
188     def informe(self,titre,txt,critique=True):
189     #--------------------------------#
190         if  critique :
191             self.afficheInfos(tr(txt),Qt.red)
192             QMessageBox.critical( self, tr(titre), tr(txt))
193         else :
194             QMessageBox.warning( self, tr(titre),tr(txt))
195
196     #--------------------------------#
197     def ajoutCommentaire(self):
198     #--------------------------------#
199         if self.tree.selectedItems()==[] :
200             QMessageBox.warning( self, tr("Pas de noeud selectionne"),tr("Selectionnez un Noeud \nLe commentaire sera place apres le noeud selectionne"))
201             return
202         noeudAvantCommentaire=self.tree.selectedItems()[0]
203         if noeudAvantCommentaire ==self.tree.racine :
204             self.tree.racine.appendChild("COMMENTAIRE",pos=0)
205             return
206         noeudAvantCommentaire.addComment(True)
207
208
209     #----------------------------------------------#
210     def _viewTextExecute(self, txt, prefix, suffix):
211     #----------------------------------------------#
212         self.w = ViewText( self.QWParent )
213         self.w.setWindowTitle( "execution" )
214         self.monExe=QProcess(self.w)
215         pid=self.monExe.pid()
216         nomFichier = self.__generateTempFilename(prefix, suffix = ".sh")
217         f=open(nomFichier,'w')
218         f.write(txt)
219         f.close()
220         self.monExe.readyReadStandardOutput.connect( self.readFromStdOut)
221         self.monExe.readyReadStandardError.connect( self.readFromStdErr)
222         exe='sh ' + nomFichier
223         self.monExe.start(exe)
224         self.monExe.closeWriteChannel()
225         self.w.exec_()
226         try:
227             commande="rm  "+ nomFichier
228             os.system(commande)
229         except :
230             pass
231
232     def readFromStdErr(self):
233         a=self.monExe.readAllStandardError()
234         self.w.view.append(str(a.data()))
235
236     def readFromStdOut(self) :
237         a=self.monExe.readAllStandardOutput()
238         self.w.view.append(str(a.data()))
239
240
241     #-----------------------#
242     def gestionParam(self):
243     #-----------------------#
244         w = MonWidgetCreeParam( self)
245         w.show()
246
247
248     #----------------#
249     def closeIt(self):
250     #----------------#
251         """
252         Public method called by the viewmanager to finally get rid of us.
253         """
254         if self.jdc: self.jdc.supprime()
255         self.close()
256
257     #----------------------------------------------#
258     def afficheInfos(self,message,couleur=Qt.black):
259     #----------------------------------------------#
260         if couleur=='red' : couleur = Qt.red
261         if self.sb:
262             mapalette=self.sb.palette()
263             mapalette.setColor( QPalette.WindowText, couleur )
264             self.sb.setPalette( mapalette );
265             self.sb.showMessage(message,4000)
266             self.couleur=couleur
267
268     #------------------------------#
269     def afficheAlerte(self,titre,message):
270     #------------------------------#
271     # appele par I_MACRO_ETAPE
272         QMessageBox.information( self, titre, message)
273
274     #-----------------------------------#
275     def afficheCommentaire(self,message):
276     #-----------------------------------#
277         self.labelCommentaire.setText(message)
278         QTimer.singleShot(6000, self.rendInvisible)
279
280     #----------------------#
281     def rendInvisible(self):
282     #----------------------#
283         self.labelCommentaire.setText("")
284
285     #---------------------------------------#
286     def chercheNoeudSelectionne(self,copie=1):
287     #---------------------------------------#
288         """
289           appele par Cut et Copy pour positionner self.node_selected
290         """
291         self.node_selected=[]
292         if len(self.tree.selectedItems()) == 0 : return
293         self.node_selected=self.tree.selectedItems()
294
295
296     #---------------------#
297     def handleSupprimer(self):
298     #---------------------#
299         self.chercheNoeudSelectionne()
300         if len(self.node_selected) == 0 : return
301         self.QWParent.noeud_a_editer = []
302         if self.node_selected[0]==self.tree.racine: return
303         if len(self.node_selected) == 1 : self.node_selected[0].delete()
304         else : self.node_selected[0].deleteMultiple(self.node_selected)
305
306     #---------------------#
307     def handleRechercher(self):
308     #---------------------#
309         from .monRecherche import DRecherche
310         monRechercheDialg=DRecherche(parent=self,fl=0)
311         monRechercheDialg.show()
312
313
314     #--------------------------------#
315     def handleRechercherDsCatalogue(self):
316     #-----------------------------#
317         from .monRechercheCatalogue import DRechercheCatalogue
318         monRechercheDialg=DRechercheCatalogue(self.QWParent,self)
319         monRechercheDialg.show()
320
321     #---------------------#
322     def handleDeplier(self):
323     #---------------------#
324         if self.tree == None : return
325         #self.tree.collapseAll()
326         if self.deplier :
327             #print "je plie"
328             self.tree.expandItem(self.tree.topLevelItem(0))
329             self.deplier = False
330             if self.fenetreCentraleAffichee != None  :
331                 if hasattr(self.fenetreCentraleAffichee.node,'plieToutEtReaffiche'):
332                     self.fenetreCentraleAffichee.node.plieToutEtReaffiche()
333         else:
334             #print "je deplie"
335             self.tree.expandItem(self.tree.topLevelItem(0))
336             self.deplier = True
337             if self.fenetreCentraleAffichee != None  :
338                 if hasattr(self.fenetreCentraleAffichee.node,'deplieToutEtReaffiche'):
339                     self.fenetreCentraleAffichee.node.deplieToutEtReaffiche()
340
341     #---------------------#
342     def handleEditCut(self):
343     #---------------------#
344         """
345         Stocke dans Eficas.noeud_a_editer le noeud a couper
346         """
347         #print "handleEditCut"
348         self.chercheNoeudSelectionne()
349         self.QWParent.edit="couper"
350         self.QWParent.noeud_a_editer = self.node_selected
351
352     #-----------------------#
353     def handleEditCopy(self):
354     #-----------------------#
355         """
356         Stocke dans Eficas.noeud_a_editer le noeud a copier
357         """
358         self.chercheNoeudSelectionne()
359         if len(self.node_selected) == 0 : return
360         if len(self.node_selected) == 1 : self.node_selected[0].updateNodeLabelInBlue()
361         else :  self.node_selected[0].updatePlusieursNodeLabelInBlue(self.node_selected)
362         self.QWParent.edit="copier"
363         self.QWParent.noeud_a_editer = self.node_selected
364
365     #------------------------#
366     def handleEditPaste(self):
367     #------------------------#
368         """
369         Lance la copie de l'objet place dans self.QWParent.noeud_a_editer
370         Ne permet que la copie d'objets de type Commande ou MCF
371         """
372         self.chercheNoeudSelectionne()
373         if (not(hasattr(self.QWParent,'noeud_a_editer'))) or len(self.QWParent.noeud_a_editer)==0:
374             QMessageBox.information( self,
375                         tr("Copie impossible"),
376                         tr("Veuillez selectionner un objet a copier"))
377             return
378         if len(self.node_selected) != 1 :
379             QMessageBox.information( self,
380                         tr("Copie impossible"),
381                         tr("Veuillez selectionner un seul objet : la copie se fera apres le noeud selectionne"))
382             return
383         noeudOuColler=self.node_selected[0]
384
385         if len(self.QWParent.noeud_a_editer)!=1:
386             #self.handleEditPasteMultiple()
387             QMessageBox.information( self, tr("Copie impossible"), tr("Aucun Objet n a ete copie ou coupe"))
388             return
389
390         noeudACopier=self.QWParent.noeud_a_editer[0]
391
392         if (self.QWParent.edit != "couper"):
393         #print   (noeudOuColler.item.parent.getChild(noeudOuColler.item.nom))
394             try:
395                 if noeudOuColler == self.tree.racine :
396                     child=noeudOuColler.doPastePremier(noeudACopier)
397                 else :
398                     child=noeudACopier.doPaste(noeudOuColler,'after')
399
400                 if child==None or child==0:
401                     QMessageBox.critical( self,tr( "Copie refusee"),tr('Eficas n a pas reussi a copier l objet'))
402                     self.message = ''
403                     self.afficheInfos("Copie refusee",Qt.red)
404                 if noeudACopier.treeParent.editor != noeudOuColler.treeParent.editor:
405                     try :
406                         nom=noeudACopier.item.sd.nom
407                         child.item.nommeSd(nom)
408                     except :
409                         pass
410                 return
411                 self.initModif()
412                 child.select()
413             except  :
414                 traceback.print_exc()
415                 QMessageBox.critical( self,tr( "Copie refusee"),tr('Copie refusee pour ce type d objet'))
416                 self.message = ''
417                 self.afficheInfos("Copie refusee",Qt.red)
418                 return
419
420         # il faut declarer le JDCDisplay_courant modifie
421         # suppression eventuelle du noeud selectionne
422         # si possible on renomme l objet comme le noeud couper
423
424         if (self.QWParent.edit == "couper"):
425             if noeudACopier.treeParent.editor != noeudOuColler.treeParent.editor:
426                 QMessageBox.critical( self, tr("Deplacement refuse"),tr('Deplacement refuse entre 2 fichiers. Seule la copie est autorisee '))
427
428             #if 1:
429             try :
430                 # indexNoeudACopier=noeudACopier.treeParent.children.index(noeudACopier)
431                 indexNoeudACopier=self.getTreeIndex(noeudACopier)
432                 noeudACopier.treeParent.item.deplaceEntite(indexNoeudACopier,indexNoeudOuColler,pos)
433                 noeudACopier.treeParent.buildChildren()
434
435             #else:
436             except:
437                 pass
438             self.QWParent.noeud_a_editer=[]
439
440         # on rend la copie a nouveau possible en liberant le flag edit
441         self.QWParent.edit="copier"
442         noeudACopier.select()
443
444     #----------------------------------#
445     def handleDeplaceMultiple(self):
446     #----------------------------------#
447         pass
448
449     #----------------------------------#
450     def handleEditPasteMultiple(self):
451     #----------------------------------#
452
453     # On ne garde que les niveaux "Etape"
454     # On insere dans l'ordre du JDC
455         listeNoeudsACouper=[]
456         listeIndex=[]
457         listeChild=[]
458         listeItem=[]
459         from InterfaceQT4 import compojdc
460         noeudOuColler=self.node_selected[0]
461         if not (isinstance(noeudOuColler.treeParent, compojdc.Node)):
462             QMessageBox.information( self,
463                       tr("Copie impossible a cet endroit",),
464                       tr("Veuillez selectionner une commande, un parametre, un commentaire ou une macro"))
465             return
466         indexNoeudOuColler=noeudOuColler.treeParent.children.index(noeudOuColler)
467
468         for noeud in self.QWParent.noeud_a_editer :
469             if not (isinstance(noeud.treeParent, compojdc.Node)): continue
470             indexInTree=noeud.treeParent.children.index(noeud)
471             indice = 0
472             for index in listeIndex:
473                 if index < indexInTree : indice = indice +1
474             listeIndex.insert(indice, indexInTree)
475             listeNoeudsACouper.insert(indice, noeud)
476
477         noeudJdc=noeudOuColler.treeParent
478         dejaCrees=0
479         # on les cree a l'envers parcequ'on ajoute a NoeudOuColler
480         listeIndex.reverse()
481         for index in listeIndex:
482             indexTravail=index
483             if indexNoeudOuColler < index:
484                 indexTravail=indexTravail+dejaCrees
485             noeudOuColler=noeudJdc.children[indexNoeudOuColler]
486             noeud=noeudJdc.children[indexTravail]
487             child=noeud.doPaste(noeudOuColler)
488             listeChild.append(child)
489             dejaCrees=dejaCrees+1
490
491         self.QWParent.noeud_a_editer = []
492         for i in range(len(listeIndex)):
493             noeud=noeudJdc.children[indexNoeudOuColler+1+i]
494             self.QWParent.noeud_a_editer.append(noeud)
495
496         listeASupprimer=[]
497         if self.QWParent.edit !="couper" : return
498
499         for index in listeIndex:
500             indexTravail=index
501             if indexNoeudOuColler < index:
502                 indexTravail=indexTravail+(len(listeIndex))
503             noeud=noeudJdc.children[indexTravail]
504
505             listeItem.append(noeud.item)
506             listeASupprimer.append(noeud)
507
508         for i in range(len(listeChild)):
509             self.tree.item.suppItem(listeItem[i])
510             listeChild[i].item.update(listeItem[i])
511
512         self.QWParent.noeud_a_editer = []
513
514     #----------------------------------#
515     def handleAjoutEtape(self,nomEtape):
516     #----------------------------------#
517         self.chercheNoeudSelectionne()
518         if len(self.node_selected) == 0 or self.node_selected[0] == self.tree.racine :
519             nodeOuAjouter=self.tree.racine
520             nouveau=nodeOuAjouter.appendChild(nomEtape,pos='first')
521         else :
522             nodeOuAjouter=self.node_selected[0]
523             if nodeOuAjouter != self.tree.racine :
524                 while  nodeOuAjouter.treeParent != self.tree.racine:
525                     nodeOuAjouter=nodeOuAjouter.treeParent
526             nouveau=nodeOuAjouter.appendBrother(nomEtape)
527         try :
528             self.node_selected[0].setSelected(False)
529         except : pass
530         nouveau.setSelected(True)
531         nouveau.affichePanneau()
532
533
534     #---------------------------#
535     def getFileVariable(self) :
536     #---------------------------#
537         titre = tr("Choix d'un fichier XML")
538         texte = tr("Le fichier contient une commande MODEL\n")
539         texte = texte+tr('Donnez le nom du fichier XML qui contient la description des variables')
540         QMessageBox.information( self, titre,tr(texte))
541
542         fichier = QFileDialog.getOpenFileName(self.appliEficas,
543                       tr('Ouvrir Fichier'),
544                       self.appliEficas.maConfiguration.savedir,
545                       tr('Wrapper Files (*.xml);;''All Files (*)'))
546         return  fichier
547
548     #------------#
549     def run(self):
550     #------------#
551         fonction="run"+self.code
552         if fonction in JDCEditor.__dict__: JDCEditor.__dict__[fonction](self,)
553
554     #------------#
555     def saveRun(self):
556     #------------#
557         fonction="saveRun"+self.code
558         if fonction in JDCEditor.__dict__: JDCEditor.__dict__[fonction](self,)
559
560
561 # ---------------------------------------------
562 # Methodes Non Crees dans ssIHM
563 # ---------------------------------------------
564     #---------------#
565     def runVP(self):
566     #---------------#
567         texte=self.getTextJDC("MAPVp",pourRun=1)
568         print (texte)
569
570     #---------------#
571     def runMAP(self):
572     #---------------#
573
574         if not(self.jdc.isValid()):
575             QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution MAP"))
576             return
577         if len(self.jdc.etapes) != 1 :
578             QMessageBox.critical( self, tr("Execution impossible "),tr("le JDC doit contenir un et un seul composant"))
579             return
580         if self.modified or self.fichier==None  :
581             self.fichierMapInput = self.__generateTempFilename(prefix = "map_run", suffix = ".map")
582             texte=self.getTextJDC("MAP")
583             self.writeFile( self.fichierMapInput, txt = texte)
584         else :
585             self.fichierMapInput=self.fichier
586         composant=self.jdc.etapes[0].nom.lower()[0:-5]
587
588
589         # :TRICKY: to determine if a component requires SALOME, loads the component from Eficas catalog
590         # then instantiate corresponding class and call getUseSalome() method
591         try:
592             from mapengine.spec import factory
593             mapComponent = factory.new(composant)[0]
594
595             command = "map"
596             if mapComponent.getUseSalome():
597                 command += " -r sappli"
598             textePython=(command + " run -n "+composant +" -i "+self.fichierMapInput)
599
600             #textePython="ls -l"
601             self._viewTextExecute( textePython,"map_run",".sh")
602             #try:
603             #  commande="rm  "+self.fichierMapInput
604             #   os.system(commande)
605             #except :
606             #   pass
607         except Exception as e:
608             print((traceback.print_exc()))
609
610     #-------------------#
611     def runZCRACKS(self):
612     #-------------------#
613         if not(self.jdc.isValid()):
614             QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution "))
615             return
616         if self.modified or self.fichier==None  :
617         #if 1:
618             self.fichierZcracksInput = self.__generateTempFilename(prefix = "zcracks_run", suffix = ".z7p")
619             texte=self.getTextJDC("ZCRACKS",pourRun=1)
620             self.writeFile( self.fichierZcracksInput, txt = texte)
621         else :
622             self.fichierZcracksInput=self.fichier
623         try :
624             #commande ="Zrun -zp "
625             commande="more "
626             textePython=(commande + self.fichierZcracksInput)
627             self._viewTextExecute( textePython,"run_zcracks",".sh")
628         except Exception as e:
629             print((traceback.print_exc()))
630
631     #-------------------#
632     def runCARMELCND(self):
633     #-------------------#
634         #if not(self.jdc.isValid()):
635         #   QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution "))
636         #   return
637         if self.modified or self.fichier==None  :
638             QMessageBox.critical( self, tr( "Execution impossible "),tr("Sauvegarder SVP avant l'execution "))
639             return
640         if not hasattr(self,'generator'): texte=self.getTextJDC(self.formatFichierOut)
641         from PrepareRunCarmel import prepareRunCarmel
642         fichierGenerique=os.path.basename(self.fichier).split(".")[0]
643         repMed=os.path.dirname(self.fichier)
644         repExeCarmel=self.generator.get_repExeCarmel()
645         textePython=prepareRunCarmel(repExeCarmel,repMed,fichierGenerique)
646         nomFichier = self.__generateTempFilename("carmel_run", suffix = ".sh")
647         f=open(nomFichier,'w')
648         f.write(textePython)
649         f.close()
650         commande="xterm -e sh "+nomFichier +"\n"
651         os.system(commande)
652
653     #-------------------#
654     def runCarmelCS(self):
655     #-------------------#
656         try :
657             commande="runSession pilotyacsCS.py"
658             os.system(commande)
659         except Exception as e:
660             print((traceback.print_exc()))
661
662     #-----------------------------------------------------#
663     def determineNomFichier(self,path,extension):
664     #-----------------------------------------------------#
665         if self.appliEficas.code in DictExtensions:
666             chaine1=DictExtensions[self.appliEficas.code]+" (*."+DictExtensions[self.appliEficas.code]+");;"
667             extensions= tr(chaine1+ "All Files (*)")
668         else :
669             extensions= tr("JDC (*.comm);;" "All Files (*)")
670
671         if self.appliEficas.code == "MAP" :
672             extensions = extensions + ";; Run (*.input);;"
673
674         fn = QFileDialog.getSaveFileName( self,
675                tr("sauvegarde"), path,
676                extensions,None,
677                QFileDialog.DontConfirmOverwrite)
678         if fn == None : return (0, None)
679         fn=fn[0]
680         if fn=='': return (0, None)
681
682         ext = QFileInfo(fn).suffix()
683         if ext == '': fn+=extension
684
685         if QFileInfo(fn).exists():
686             msgBox = QMessageBox(self)
687             msgBox.setWindowTitle(tr("Sauvegarde du Fichier"))
688             msgBox.setText(tr("Le fichier")+ "  "+str(fn)+ "  " +tr("existe deja"))
689             msgBox.addButton(tr("&Ecraser"),0)
690             msgBox.addButton(tr("&Abandonner"),1)
691             abort=msgBox.exec_()
692             if abort == 1 :  return (0, "")
693         return (1,fn)
694
695     #-----------------#
696     def saveRunMAP(self):
697     #-----------------#
698         extension=".input"
699         if not(self.jdc.isValid()):
700             QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
701                                  tr("Un JdC valide est necessaire pour creer un .input")
702                                   )
703             return
704         try :
705             composant=self.jdc.etapes[0].nom.lower()[0:-5]
706         except :
707             QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
708                                  tr("Choix du composant obligatoire")
709                                   )
710             return
711         if hasattr(self.maConfiguration, "savedir"): path=self.maConfiguration.savedir
712         else : path='C:/'
713
714         monNomFichier=""
715         if self.fichier is not None and self.fichier != "" :
716             maBase=str(QFileInfo(self.fichier).baseName())+".input"
717             monPath=str(QFileInfo(self.fichier).absolutePath())
718             monNomFichier=os.path.join(monPath,maBase)
719         elif hasattr(self,'monNomFichierInput'):
720             monNomFichier=self.monNomFichierInput
721
722
723         monDialog=QFileDialog(self.appliEficas)
724         monDialog.setDirectory (path)
725         monDialog.setWindowTitle ("Save")
726
727         for c in monDialog.children():
728             if isinstance(c,QDialogButtonBox):
729                 for b in c.children():
730                     if isinstance(b,QPushButton):
731                         avant=b.text()
732                         if avant=="&Open": b.setText("Save")
733         mesFiltres= "input Map (*.input);;All Files (*)"
734         monDialog.setNameFilters(mesFiltres)
735         if monNomFichier!="" : monDialog.selectFile(monNomFichier)
736         BOk=monDialog.exec_()
737         if BOk==0: return
738         fn=str(monDialog.selectedFiles()[0])
739         if fn == "" or fn == None : return
740         if not fn.endswith(".input"):
741             fn += ".input"
742         self.monNomFichierInput=fn
743
744         if not hasattr(self, 'fichierMapInput') or not self.fichierMapInput or not os.path.exists(self.fichierMapInput):
745             self.fichierMapInput = self.__generateTempFilename(prefix = "map_run", suffix = ".map")
746             texte=self.getTextJDC("MAP")
747             self.writeFile( self.fichierMapInput, txt = texte)
748
749         cmd = ("map gen -t dat -n " + composant + " -i " + self.fichierMapInput + " -o " + fn)
750         p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
751         (output, err) = p.communicate()
752
753
754     #-----------------#
755     def saveRunPSEN(self):
756     #-----------------#
757         #print ("saveRunPSEN")
758         self.saveFile()
759
760
761
762     #-----------------------------------------#
763     def handleAjoutGroup(self,listeGroup):
764     #-----------------------------------------#
765         try :
766         #if 1:
767             from ajoutGroupe import handleAjoutGroupFiltre
768             #print listeGroup
769             handleAjoutGroupFiltre(self,listeGroup)
770             #print "apres handleAjoutGroupFiltre"
771         except :
772         #else :
773             pass
774
775
776     #-----------------------------------------------------------------#
777     def saveCompleteFile(self, path = None, saveas= 0,formatLigne="beautifie"):
778     #-----------------------------------------------------------------#
779         extension='.casR'
780         fn = self.fichierComplet
781         #saveas=True # Pour forcer le nom
782         self.generator=self.maConfiguration.mesGenerators.plugins[self.formatFichierOut]()
783         if self.fichierComplet is None or saveas:
784             if path is None: path=self.maConfiguration.savedir
785             bOK, fn=self.determineNomFichier(path,extension)
786             if bOK == 0 : return (0, None)
787             if fn == None : return (0, None)
788             if fn== '' : return (0, None)
789
790             ulfile = os.path.abspath(fn)
791             self.appliEficas.maConfiguration.savedir=os.path.split(ulfile)[0]
792             fn = QDir.toNativeSeparators(fn)
793
794         self.fichierComplet = os.path.splitext(fn)[0]+extension
795
796         if hasattr(self.generator, "writeComplet"):
797             self.generator.writeComplet(self.fichierComplet,self.jdc,config=self.appliEficas.maConfiguration,appliEficas=self.appliEficas)
798
799         if self.salome : self.appliEficas.addJdcInSalome( self.fichierComplet)
800
801         self.modified = 0
802         nouveauTitre=self.titre+"              "+str(os.path.basename(self.fichierComplet))
803         self.appliEficas.setWindowTitle(nouveauTitre)
804         return (1, self.fichierComplet)
805
806     #-----------------------------------------------------------------#
807     def saveFile(self, path = None, saveas= 0,formatLigne="beautifie"):
808     #-----------------------------------------------------------------#
809         """
810         Public slot to save the text to a file.
811
812         @param path directory to save the file in (string or QString)
813         @return tuple of two values (boolean, string) giving a success indicator and
814             the name of the saved file
815         """
816
817         self.modified=1
818         if not self.modified and not saveas:
819             return (0, None)      # do nothing if text wasn't changed
820
821         if self.appliEficas.code in DictExtensions :
822             extension=DictExtensions[self.appliEficas.code]
823         else :
824             extension='.comm'
825
826         newName = None
827         fn = self.fichier
828         if self.fichier is None or saveas:
829             if path is None: path=self.maConfiguration.savedir
830             bOK, fn=self.determineNomFichier(path,extension)
831             if bOK == 0 : return (0, None)
832             if fn == None : return (0, None)
833             if fn== '' : return (0, None)
834
835             ulfile = os.path.abspath(fn)
836             self.appliEficas.maConfiguration.savedir=os.path.split(ulfile)[0]
837             fn = QDir.toNativeSeparators(fn)
838             newName = fn
839
840
841         if not (self.writeFile(fn,formatLigne=formatLigne)): return (0, None)
842         self.fichier = fn
843         self.modified  = False
844         if self.fileInfo is None or saveas:
845             self.fileInfo = QFileInfo(self.fichier)
846             self.fileInfo.setCaching(0)
847         self.lastModified = self.fileInfo.lastModified()
848         if newName is not None:
849             self.appliEficas.addToRecentList(newName)
850             self.tree.racine.item.getObject().nom=os.path.basename(newName)
851             self.tree.racine.updateNodeLabel()
852
853
854         if  self.jdc.cata.modeleMetier:self.jdc.toXml(self.fichier)
855         if  self.jdc.cata.modeleMetier and self.jdc.isValid():
856             if self.generator != self.XMLgenerator :
857                 self.XMLgenerator.gener(self.jdc)
858                 self.XMLgenerator.writeDefault(fn)
859
860         if self.jdc.isValid() != 0 and hasattr(self.generator, "writeDefault"):
861         #if hasattr(self.generator, "writeDefault"):
862             self.generator.writeDefault(fn)
863         elif self.code=="TELEMAC" and hasattr(self.generator, "writeDefault"):
864             msgBox = QMessageBox(None)
865             msgBox.setWindowTitle(tr("Fichier .cas invalide / incomplet"))
866             msgBox.setText(tr("Le fichier .cas est invalide / incomplet"))
867             msgBox.addButton(tr("&Sauvegarder"),1)
868             msgBox.addButton(tr("&Quitter sans sauvegarder"),0)
869             msgBox.addButton(tr("&Annuler"),2)
870             res=msgBox.exec_()
871             if res == 0 :
872                 self.generator.writeDefault(fn)
873                 return (1, self.fichier)
874             if res == 2 : return (0, None)
875             if self.appliEficas.salome : self.appliEficas.close()
876             else : sys.exit(1)
877
878         if self.salome :
879             self.appliEficas.addJdcInSalome( self.fichier)
880         self.modified = 0
881         nouveauTitre=self.titre+"              "+str(os.path.basename(self.fichier))
882         self.appliEficas.setWindowTitle(nouveauTitre)
883
884         return (1, self.fichier)
885 #
886
887     #----------------------------------------------#
888     def sauveLigneFile(self):
889     #----------------------------------------------#
890         self.modified=1
891         return self.saveFile(formatLigne="Ligne")
892
893
894     #----------------------------------------------#
895     def saveFileAs(self, path = None,fileName=None):
896     #----------------------------------------------#
897         """
898         Public slot to save a file with a new name.
899
900         @param path directory to save the file in (string or QString)
901         @return tuple of two values (boolean, string) giving a success indicator and
902             the name of the saved file
903         """
904         if fileName != None :
905             self.fichier = fileName
906             return self.saveFile()
907         return self.saveFile(path,1,"beautifie")
908
909
910
911     #---------------------------------------------#
912     def getFile(self,unite=None,fic_origine = ''):
913     #---------------------------------------------#
914     # appele par I_JDC
915         ulfile  = None
916         jdcText = ""
917
918         titre  = ""
919
920         if unite :
921             titre = tr("Choix unite %d ", unite)
922             texte = tr("Le fichier %s contient une commande INCLUDE \n",  str(fic_origine)) +"\n"
923             texte = texte+ tr("Donnez le nom du fichier correspondant a l unite logique ") + repr(unite)
924             labeltexte = tr('Fichier pour unite ') + repr( unite)
925         else:
926             titre = tr("Choix d'un fichier de poursuite")
927             texte = tr("Le fichier %s contient une commande POURSUITE\n", fic_origine)
928             texte = texte+tr('Donnez le nom du fichier dont vous \n voulez faire une poursuite')
929
930         QMessageBox.information( self, titre,texte)
931         fn = QFileDialog.getOpenFileName(self.appliEficas,
932                    titre,
933                    self.appliEficas.maConfiguration.savedir)
934
935         # ce retour est impose par le getFile d'I_JDC
936         if fn== '' : return None," "
937         if not fn : return (0, " ")
938         fn=fn[0]
939
940         ulfile = os.path.abspath(fn)
941         self.appliEficas.maConfiguration.savedir=os.path.split(ulfile)[0]
942
943         # On utilise le convertisseur defini par formatFichierIn
944         source=self.getSource(ulfile)
945         if source:
946             # On a reussia convertir le fichier self.ulfile
947             jdcText = source
948         else:
949             # Une erreur a ete rencontree
950             jdcText = ''
951         return ulfile, jdcText
952
953     #-----------------------------------#
954     def updateJdc(self, etape,texte):
955     #------------------------------------#
956     # ajoute une etape  de JdC a partir d un texte
957         CONTEXT.setCurrentStep(etape)
958         etape.buildIncludeEtape(texte)
959         if not (etape.text_included_converted) :
960             QMessageBox.information( self,
961                        tr("Impossible d importer le texte"),
962                        etape.text_included_error)
963
964         self.tree.racine.buildChildren()
965
966     #-----------------------------------#
967     def updateJdcEtape(self, itemApres,texte):
968     #------------------------------------#
969     # ajoute une etape  de JdC a partir d un texte
970         monItem=itemApres
971         etape=monItem.item.object
972
973         CONTEXT.setCurrentStep(etape)
974         try :
975             ok=etape.buildIncludeEtape(texte)
976         except :
977             ok=0
978         if not ok :
979             QMessageBox.information( self,
980                        tr("Import texte"),
981                        tr("Impossible d importer le texte"))
982         self.tree.racine.buildChildren()
983         return ok
984
985     #-------------------------------------------#
986     def updateJdcAfterEtape(self, etape,texte):
987     #--------------------------------------------#
988     # ajoute une etape  de JdC a partir d un texte
989         CONTEXT.setCurrentStep(etape)
990         try :
991             ok=etape.buildIncludeEtape(texte,doitEtreValide=0)
992         except :
993             ok=0
994         if not ok :
995             QMessageBox.information( self,
996                        tr("Import texte"),
997                        tr("Impossible d importer le texte"))
998         self.tree.racine.buildChildren()
999         return ok
1000
1001
1002     #-------------------------------------#
1003     def deleteEtape(self,etape):
1004     #-------------------------------------#
1005     # dans le JDC
1006         self.jdc.suppEntite(etape)
1007
1008
1009     #-----------------------------------------
1010     def initSplitterSizes(self, nbWidget=3):
1011     #-----------------------------------------
1012         #print ("je passe ds initSplitterSizes", nbWidget)
1013
1014         if   self.code in [ 'Adao', 'ADAO','MAP' ] : self.splitterSizes3=[1,1550,300]
1015         #elif self.code in [ 'MAP']            : self.splitterSizes3=[700,300]
1016         else                                  : self.splitterSizes3=[150,1000,300]
1017
1018         if   self.code in [ 'Adao', 'ADAO','MAP' ] : self.splitterSizes2=[5,1500]
1019         else                                  : self.splitterSizes2=[300,1000]
1020
1021
1022     #-----------------------------------------
1023     def restoreSplitterSizes(self,nbWidget=3):
1024     #----------------------------------------
1025
1026         #traceback.print_stack()
1027         #print ("je passe ds restoreSplitterSizes")
1028         if not(hasattr(self,'splitter')) : return
1029         if nbWidget==2  : newSizes=self.splitterSizes2
1030         if nbWidget==3  : newSizes=self.splitterSizes3
1031         #self.inhibeSplitter = 1
1032         #print (newSizes)
1033         self.splitter.setSizes(newSizes)
1034         #self.inhibeSplitter = 0
1035         QApplication.processEvents()
1036         # seule la fentetre du milieu est necessaire
1037         self.splitter.widget(1).resizeEvent=self.saveSplitterSizes
1038
1039     #-----------------------------------------
1040     def saveSplitterSizes(self,event):
1041     #-----------------------------------------
1042         #print ("je passe ds saveSplitterSizes")
1043         if self.inhibeSplitter : return
1044         if self.widgetOptionnel == None  : self.splitterSizes2 = self.splitter.sizes()[0:2]
1045         else                             : self.splitterSizes3 = self.splitter.sizes()[0:3]
1046
1047     #------------------------
1048     def fermeOptionnel(self):
1049     #------------------------
1050         if self.widgetOptionnel == None : return
1051
1052         self.inhibeSplitter=1
1053         self.widgetOptionnel.setParent(None)
1054         self.widgetOptionnel.close()
1055         self.widgetOptionnel.deleteLater()
1056         self.widgetOptionnel=None
1057         self.inhibeSplitter=0
1058         self.restoreSplitterSizes(2)
1059
1060     #------------------------
1061     def ajoutOptionnel(self):
1062     #------------------------
1063         #if len(self.splitterSizes) == 2 : self.splitterSizes.append(self.oldSizeWidgetOptionnel)
1064         #else : self.splitterSizes[2] = self.oldSizeWidgetOptionnel # ceinture pour les close bizarres
1065         #self.splitterSizes[1] = self.splitterSizes[1] - self.splitterSizes[2]
1066
1067         self.restoreSplitterSizes(3)
1068
1069
1070     #------------------------
1071     def fermeArbre(self):
1072     #------------------------
1073         #print (self.widgetTree)
1074         self.oldWidgetTree=self.widgetTree
1075         self.widgetTree.hide()
1076         #self.widgetTree=None
1077
1078     #------------------------
1079     def ouvreArbre(self):
1080     #------------------------
1081         #print ('je passe la')
1082         #print (self.widgetTree)
1083         #self.widgetTree=self.oldWidgetTree
1084         self.widgetTree.show()
1085         #self.restoreSplitterSizes(3)
1086
1087     #-----------------------
1088     def getEtapeCourante(self) :
1089     #-----------------------
1090         if len(self.tree.selectedItems()) != 1 : return None
1091         etape=self.tree.selectedItems()[0].item.object.getEtape()
1092         return etape
1093     #-----------------------------
1094     def getTreeIndex(self,noeud):
1095     #----------------------------
1096         indexNoeud=-1
1097         if noeud in noeud.treeParent.children :
1098             indexNoeud=noeud.treeParent.children.index(noeud)
1099         else :
1100             if hasattr(noeud,'vraiParent') :
1101                 noeudVrai = noeud
1102                 noeudVraiParent = noeud.vraiParent
1103                 while noeudVraiParent != noeud.treeParent and hasattr(noeudVraiParent,'vraiParent') :
1104                     noeudVrai = noeudVraiParent
1105                     noeudVraiParent = noeudVraiParent.vraiParent
1106                     pass
1107                 if noeudVraiParent == noeud.treeParent :
1108                     indexNoeud=noeud.treeParent.children.index(noeudVrai)
1109                     pass
1110                 pass
1111             pass
1112         return indexNoeud
1113
1114     #-------------------#  Pour execution avec output et error dans le bash
1115     def runPSEN(self):
1116     #-------------------#
1117
1118         #if self.modified or self.fichier==None  : self.saveFile()
1119         self.saveFile()
1120
1121         #lancement avec le .bat
1122         path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../','../','PSEN_Eficas','PSEN'))
1123         WrapperFilePath = os.path.join(path1, 'PSSEWrapper.py')
1124         import subprocess
1125         p = subprocess.Popen(['python',WrapperFilePath])
1126         (out,err)=p.communicate()
1127         print (out)
1128         print (err)
1129
1130     #-------------------#  Pour execution avec output et error dans le bash
1131     def runPSEN_N1(self):
1132     #-------------------#
1133
1134
1135         self.saveFile()
1136         path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../','../','ProcessOutputs_Eficas','TreatOutputs'))
1137         sys.path.append(path1)
1138
1139         if not(self.jdc.isValid()):
1140             QMessageBox.information( self, tr( "Unvalid JDC"),tr("incorrect keywords will be ignored"))
1141         if 'dicoImbrique' in generator.plugins:
1142             self.generator=generator.plugins['dicoImbrique']()
1143             jdc_formate=self.generator.gener(self.jdc)
1144             dico=self.generator.Dico
1145
1146             ###to delete
1147             #fileDico =  r'C:\Logiciels DER\PSEN_V16\Code\ProcessOutputs_Eficas\TreatOutputs\dicoN1.py'
1148             fileDico =  os.path.join(path1, 'dicoN1.py') #r'C:\Logiciels DER\PSEN_V16\Code\ProcessOutputs_Eficas\TreatOutputs\dicoN1.py'
1149             f = open( str(fileDico), 'w')
1150             f.write("Dico =" + str(dico) )
1151             f.close()
1152             ###
1153
1154
1155         print ('in runPSEN_N1', dico)
1156         print (dico)
1157         from Run import run
1158         run(dico)
1159         #res,txt_exception=run(dico)
1160         #if res : QMessageBox.information( self, tr("fin de script run"), txt_exception)
1161         #else  : QMessageBox.critical( self, tr("Erreur fatale script run"), txt_exception)
1162
1163     #-------------------#  Pour execution avec output et error dans le bash
1164     def process_N1(self):
1165     #-------------------#
1166
1167         path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../','../','ProcessOutputs_Eficas','TreatOutputs'))
1168         sys.path.append(path1)
1169
1170
1171         if 'dicoImbrique' in generator.plugins:
1172             self.generator=generator.plugins['dicoImbrique']()
1173             jdc_formate=self.generator.gener(self.jdc)
1174             dico=self.getDico() #generator.Dico
1175
1176
1177             for k in dico['CONTINGENCY_PROCESSING']:
1178             #print (k)
1179                 if k[0:19] == 'Component_List_For_' or k[0:21] =='Contingency_List_For_' :
1180                     newK=k.replace('__',' ')
1181                     l="'"+str(newK)+"'"
1182                     dico['CONTINGENCY_PROCESSING'][l]=dico['CONTINGENCY_PROCESSING'][k]
1183                     del dico['CONTINGENCY_PROCESSING'][k]
1184
1185             ###to delete
1186             fileDico =  os.path.join(path1, 'dicoN1_process.py')
1187             f = open( str(fileDico), 'w')
1188             f.write("Dico =" + str(dico) )
1189             f.close()
1190             ###
1191             return dico
1192
1193         #return self.getDico()
1194
1195     #-------------------#  Pour execution avec output et error dans le bash
1196     def process_VP(self):
1197     #-------------------#
1198         if 'dicoImbrique' in generator.plugins:
1199             self.generator=generator.plugins['dicoImbrique']()
1200             jdc_formate=self.generator.gener(self.jdc)
1201             dico=self.getDico() #generator.Dico
1202             return dico
1203
1204 if __name__ == "__main__":
1205     print ('in main')