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