Salome HOME
Merge branch 'nouvelEficas' of http://git.forge-pleiade.der.edf.fr/git/eficas into...
[tools/eficas.git] / InterfaceQT4 / editor.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013   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 import types,sys,os, re
21 import  subprocess
22 import traceback
23 from PyQt4 import *
24 from PyQt4.QtGui  import *
25 from PyQt4.QtCore import *
26 import time
27 from datetime import date
28 from Extensions.i18n import tr
29
30
31 # Modules Eficas
32
33 import convert, generator
34 from Editeur        import session
35 from Editeur        import comploader
36 from Editeur        import Objecttreeitem
37 from desBaseWidget  import Ui_baseWidget
38 from monViewTexte   import ViewText 
39 from monWidgetParam import MonWidgetParam 
40 import browser
41 import readercata
42
43 DictExtensions= {"MAP" : ".map"}
44
45
46
47 class JDCEditor(Ui_baseWidget,QtGui.QWidget):
48 # ----------------------------------------- #
49     """
50        Editeur de jdc
51     """
52
53     def __init__ (self,appli,fichier = None, jdc = None, QWParent=None, units = None, include=0 , vm=None):
54     #----------------------------------------------------------------------------------------------------------#
55
56         QtGui.QWidget.__init__(self,None)
57         self.setupUi(self)
58         self.monOptionnel=None
59         self.fenetreCentraleAffichee=None
60         self.appliEficas = appli
61         self.appli       = appli  #---- attendu par IHM
62         self.vm          = vm
63         self.fichier     = fichier
64         self.jdc         = jdc
65         self.first       = True
66         self.QWParent    = QWParent
67          
68         if appli != None :
69            self.salome =  self.appliEficas.salome
70         else :
71            self.salome=0
72            print "dans JDC pas d appli ????????"
73
74         # ces attributs sont mis a jour par definitCode appelee par newEditor
75         self.code = self.appliEficas.CONFIGURATION.code
76         self.affiche_alpha=1
77         if self.code in ['MAP','Adao'] : 
78            self.widgetTree.close()
79            self.widgetTree=None
80            self.appliEficas.resize(1440,self.appliEficas.height())
81         else :
82            self.appliEficas.resize(2000,self.appliEficas.height())
83
84         self.version_code = session.d_env.cata
85
86         if not hasattr ( self.appliEficas, 'readercata') or  self.appliEficas.multi==True:
87            self.readercata  = readercata.READERCATA( self, self.appliEficas )
88            self.appliEficas.readercata=self.readercata
89         else :
90            self.readercata=self.appliEficas.readercata
91         if self.readercata.fic_cata == None : return    #Sortie Salome
92         self.titre=self.readercata.titre
93
94         self.format =  self.appliEficas.format_fichier
95
96         self.dict_reels={}
97         self.liste_simp_reel=[]
98         self.ihm="QT"
99
100         nameConf='configuration_'+self.code
101         configuration=__import__(nameConf)
102         self.CONFIGURATION = self.appliEficas.CONFIGURATION
103         self.CONFIGStyle =   self.appliEficas.CONFIGStyle
104
105         try:
106           self.CONFIGURATION.generator_module
107           _module = __import__(self.CONFIGURATION.generator_module)
108           info = _module.entryPoint()
109           generator.plugins.addEntryPoint(info)
110         except:
111           pass
112
113         try:
114           self.CONFIGURATION.convert_module
115           _module = __import__(self.CONFIGURATION.convert_module)
116           info = _module.entryPoint()
117           convert.plugins.addEntryPoint(info)
118         except :
119           pass
120
121         self.sb = None
122         if hasattr(self.appliEficas,"statusBar"):
123            self.sb = self.appliEficas.statusBar()
124
125         self.fileInfo       = None
126         self.lastModified   = 0
127
128         self.modified   = False
129         self.isReadOnly = False
130         self.node_selected = []
131         self.deplier = True
132         self.message=''
133
134         self.Commandes_Ordre_Catalogue =self.readercata.Commandes_Ordre_Catalogue
135
136         #------- construction du jdc --------------
137
138         jdc_item = None
139         self.mode_nouv_commande=self.readercata.mode_nouv_commande
140
141         self.nouveau=0
142         if self.fichier is not None:        #  fichier jdc fourni
143             self.fileInfo = QFileInfo(self.fichier)
144             self.fileInfo.setCaching(0)
145             if jdc==None :
146                try :
147                    self.jdc = self.readFile(self.fichier)
148                except :
149                    print "mauvaise lecture"
150             else :
151                self.jdc=jdc
152             if self.jdc is not None and units is not None:
153                self.jdc.recorded_units=units
154                self.jdc.old_recorded_units=units
155         else:
156             if not self.jdc:                   #  nouveau jdc
157                 if not include :
158                    self.jdc = self._newJDC(units=units)
159                 else :
160                    self.jdc = self._newJDCInclude(units=units)
161                 self.nouveau=1
162
163         if self.jdc:
164             self.jdc.appli = self
165             self.jdc.lang    = self.appli.langue
166             txt_exception  = None
167             if not jdc:
168                 self.jdc.analyse()
169                 txt_exception = self.jdc.cr.get_mess_exception()
170             if txt_exception:
171                 self.jdc = None
172                 qApp.restoreOverrideCursor()
173                 self.affiche_infos(tr("Erreur fatale au chargement de %s",str(fichier)),Qt.red)
174                 if (self.appliEficas.ssIhm == False) : QMessageBox.critical( self, tr("Erreur fatale au chargement d'un fichier"), txt_exception)
175             else:
176                 comploader.charger_composants("QT")
177                 jdc_item=Objecttreeitem.make_objecttreeitem( self, "nom", self.jdc )
178                 if (not self.jdc.isvalid()) and (not self.nouveau) and (self.appliEficas.ssIhm == False):
179                     self.viewJdcRapport()
180
181         if jdc_item:
182             self.tree = browser.JDCTree( jdc_item,  self )
183         self.jdc.aReafficher=False
184         self.appliEficas.construitMenu()
185
186     #--------------------------------#
187     def _newJDC( self ,units = None):
188     #--------------------------------#
189         """
190         Initialise un nouveau JDC vierge
191         """
192         self.modified=1
193         CONTEXT.unset_current_step()
194
195         texte=""
196         if self.code == "CARMELCND" : texte=self._newJDCCND()
197         if self.code == "ZCRACKS" : texte=self._newZCRACKS()
198         if self.code == "TELEMAC" : texte=self._newTELEMAC()
199         #   texte=self.newTexteCND
200        
201         jdc=self.readercata.cata[0].JdC( procedure =texte,
202                                          appli=self,
203                                          cata=self.readercata.cata,
204                                          cata_ord_dico=self.readercata.cata_ordonne_dico,
205                                          rep_mat=self.CONFIGURATION.rep_mat
206                                         )
207         jdc.lang    = self.appli.langue
208         if units is not None:
209            jdc.recorded_units=units
210            jdc.old_recorded_units=units
211         ## PNPN est ce que la ligne suivante est bien utile ?
212         if texte == "" :jdc.analyse()
213         return jdc
214
215     #--------------------------------#
216     def _newJDCInclude( self ,units = None):
217     #--------------------------------#
218         """
219         Initialise un nouveau JDC vierge
220         """
221         import Extensions.jdc_include
222         JdC_aux=Extensions.jdc_include.JdC_include
223         CONTEXT.unset_current_step()
224
225         jaux=self.readercata.cata[0].JdC( procedure="",
226                                appli=self,
227                                cata=self.readercata.cata,
228                                cata_ord_dico=self.readercata.cata_ordonne_dico,
229                                rep_mat=self.CONFIGURATION.rep_mat,
230                               )
231         jaux.analyse()
232
233         J=JdC_aux( procedure="",
234                    appli=self,
235                    cata=self.readercata.cata,
236                    cata_ord_dico=self.readercata.cata_ordonne_dico,
237                    jdc_pere=jaux,
238                    rep_mat=self.CONFIGURATION.rep_mat,
239                    )
240         J.analyse()
241         if units is not None:
242            J.recorded_units=units
243            J.old_recorded_units=units
244         return J
245
246
247     #-------------------------------#
248     def readFile(self, fn):
249     #--------------------------------#
250         """
251         Public slot to read the text from a file.
252         @param fn filename to read from (string or QString)
253         """
254         fn = unicode(fn)
255
256         # ------------------------------------------------------------------------------------
257         #                         charge le JDC
258         # ------------------------------------------------------------------------------------
259
260         jdcName=os.path.basename(fn)
261         # Il faut convertir le contenu du fichier en fonction du format
262         if convert.plugins.has_key( self.appliEficas.format_fichier_in ):
263              # Le convertisseur existe on l'utilise
264              #appli = self
265              p=convert.plugins[self.appliEficas.format_fichier_in]()
266              p.readfile(fn)
267              if p.text=="" : self.nouveau=1
268              pareil,texteNew=self.verifieCHECKSUM(p.text)
269              #if texteNew == ""
270              if pareil == False and (self.appliEficas.ssIhm == False) :
271                 QMessageBox.warning( self, tr("fichier modifie"),tr("Attention! fichier change hors EFICAS"))
272              p.text=texteNew
273              memeVersion,texteNew=self.verifieVersionCataDuJDC(p.text)
274              if memeVersion == 0 : texteNew=self.traduitCatalogue(texteNew)
275              p.text=texteNew
276              text=p.convert('exec',self.appliEficas)
277              if not p.cr.estvide():
278                 self.affiche_infos("Erreur a la conversion",Qt.red)
279         else :
280             self.affiche_infos("Type de fichier non reconnu",Qt.red)
281             if self.appliEficas.ssIhm == False:
282                     QMessageBox.critical( self, tr("Type de fichier non reconnu"),
283                     tr("EFICAS ne sait pas ouvrir le type de fichier %s" ,self.appliEficas.format_fichier_in))
284             return None
285
286         CONTEXT.unset_current_step()
287         jdc=self.readercata.cata[0].JdC(procedure=text,
288                                     appli=self,
289                                     cata=self.readercata.cata,
290                                     cata_ord_dico=self.readercata.cata_ordonne_dico,
291                                     nom=jdcName,
292                                     rep_mat=self.CONFIGURATION.rep_mat
293                                    )
294         # ----------------------------------------------------
295         #      charge le JDC fin
296         # ----------------------------------------------------
297         self.modified = False
298
299 #        qApp.restoreOverrideCursor()
300         if self.fileInfo!= None :
301            self.lastModified = self.fileInfo.lastModified()
302         else :
303            self.lastModified = 1
304         nouveauTitre=self.titre+"              "+str(os.path.basename(self.fichier))
305         self.appliEficas.setWindowTitle(nouveauTitre)
306         return jdc
307
308
309     #-----------------------#
310     def get_source(self,file):
311     #-----------------------#
312
313         # Il faut convertir le contenu du fichier en fonction du format
314         if convert.plugins.has_key(self.format):
315             # Le convertisseur existe on l'utilise
316             p=convert.plugins[self.format]()
317             p.readfile(file)
318             text=p.convert('execnoparseur')
319             if not p.cr.estvide():
320                 self.affiche_infos("Erreur a la conversion",Qt.red)
321             return text
322         else:
323             # Il n'existe pas c'est une erreur
324             self.affiche_infos("Type de fichier non reconnu",Qt.red)
325             QMessageBox.critical( self, tr("Type de fichier non reconnu"),tr("EFICAS ne sait pas ouvrir ce type de fichier"))
326             return None
327
328     #-----------------------------------------------------------------------#
329     def _viewText(self, txt, caption = "FILE_VIEWER",largeur=1200,hauteur=600):
330     #--------------------------------------------------------------------#
331         w = ViewText( self.QWParent,self ,caption,txt,largeur,hauteur)
332         w.show()
333     #
334
335     #----------------------------------------------#
336     def __generateTempFilename(self, prefix, suffix):
337     #----------------------------------------------#
338         import tempfile
339         (fd, filename) = tempfile.mkstemp(prefix=prefix, suffix=suffix)
340         os.close(fd)
341         return filename
342     #
343
344
345     #----------------------------------------------#
346     def _viewTextExecute(self, txt, prefix, suffix):
347     #----------------------------------------------#
348         self.w = ViewText( self.QWParent )
349         self.w.setWindowTitle( "execution" )
350         self.monExe=QProcess(self.w)
351         pid=self.monExe.pid()
352         nomFichier = self.__generateTempFilename(prefix, suffix = ".sh")
353         f=open(nomFichier,'w')
354         f.write(txt)
355         f.close()
356         self.connect(self.monExe, SIGNAL("readyReadStandardOutput()"), self.readFromStdOut )
357         self.connect(self.monExe, SIGNAL("readyReadStandardError()"), self.readFromStdErr )
358         exe='sh /tmp/test.sh'
359         self.monExe.start(exe)
360         self.monExe.closeWriteChannel()
361         self.w.exec_()
362         try:
363           commande="rm  "+ nomFichier
364           os.system(commande)
365         except :
366           pass
367
368
369     def readFromStdErr(self):
370         a=self.monExe.readAllStandardError()
371         self.w.view.append(QString.fromUtf8(a.data(),len(a))) ;
372
373     def readFromStdOut(self) :
374         a=self.monExe.readAllStandardOutput()
375         self.w.view.append(QString.fromUtf8(a.data(),len(a))) ;
376         
377
378
379     #-----------------------#
380     def gestionParam(self):
381     #-----------------------#
382         w = MonWidgetParam( self)
383         w.show()
384
385     #-----------------------#
386     def viewJdcSource(self):
387     #-----------------------#
388         f=open(self.fichier,'r')
389         texteSource=f.read()
390         f.close()
391         self._viewText(texteSource, "JDC_SOURCE")
392
393     #-----------------------#
394     def viewJdcPy(self):
395     #-----------------------#
396         strSource = str( self.get_text_JDC(self.format) )
397         self._viewText(strSource, "JDC_RESULTAT")
398
399     #-----------------------#
400     def viewJdcRapport(self):
401     #-----------------------#
402         strRapport = unicode( self.jdc.report() )
403         self._viewText(strRapport, "JDC_RAPPORT")
404
405     #----------------#
406     def closeIt(self):
407     #----------------#
408         """
409         Public method called by the viewmanager to finally get rid of us.
410         """
411         if self.jdc:
412             self.jdc.supprime()
413         self.close()
414
415     #----------------------------------------------#
416     def affiche_infos(self,message,couleur=Qt.black):
417     #----------------------------------------------#
418         if self.sb:
419            mapalette=self.sb.palette()
420            from PyQt4.QtGui import QPalette
421            mapalette.setColor( QPalette.WindowText, couleur )
422            self.sb.setPalette( mapalette );
423            self.sb.showMessage(QString.fromUtf8(message))#,2000)
424
425     #------------------------------#
426     def affiche_alerte(self,titre,message):
427     #------------------------------#
428     # appele par I_MACRO_ETAPE
429         QMessageBox.information( self, titre, message)
430
431     #-------------------#
432     def init_modif(self):
433     #-------------------#
434       """
435           Met l'attribut modified a 'o' : utilise par Eficas pour savoir
436           si un JDC doit etre sauvegarde avant destruction ou non
437       """
438       self.modified = True
439
440     #---------------------------------------#
441     def chercheNoeudSelectionne(self,copie=1):
442     #---------------------------------------#
443       """
444         appele par Cut et Copy pour positionner self.node_selected
445       """
446       self.node_selected=[]
447       if len(self.tree.selectedItems()) == 0 : return
448       self.node_selected=self.tree.selectedItems()
449
450
451     #---------------------#
452     def handleSupprimer(self):
453     #---------------------#
454       self.chercheNoeudSelectionne()
455       if len(self.node_selected) == 0 : return
456       self.QWParent.noeud_a_editer = []
457       if self.node_selected[0]==self.tree.racine: return
458       if len(self.node_selected) == 1 : self.node_selected[0].delete()
459       else : self.node_selected[0].deleteMultiple(self.node_selected)
460
461     #---------------------#
462     def handleRechercher(self):
463     #---------------------#
464       from monRecherche import DRecherche
465       monRechercheDialg=DRecherche(parent=self,fl=0)
466       monRechercheDialg.show()
467
468     #---------------------#
469     def handleDeplier(self):
470     #---------------------#
471        if self.tree == None : return
472        self.tree.collapseAll()
473        if self.deplier :
474           self.tree.collapseItem(self.tree.topLevelItem(0))
475           self.deplier = False
476        else:
477           self.tree.expandItem(self.tree.topLevelItem(0))
478           self.deplier = True
479
480     #---------------------#
481     def handleEditCut(self):
482     #---------------------#
483       """
484       Stocke dans Eficas.noeud_a_editer le noeud a couper
485       """
486       #print "handleEditCut"
487       self.chercheNoeudSelectionne()
488       self.QWParent.edit="couper"
489       self.QWParent.noeud_a_editer = self.node_selected
490
491     #-----------------------#
492     def handleEditCopy(self):
493     #-----------------------#
494       """
495       Stocke dans Eficas.noeud_a_editer le noeud a copier
496       """
497       self.chercheNoeudSelectionne()
498       if len(self.node_selected) == 0 : return
499       if len(self.node_selected) == 1 : self.node_selected[0].update_node_label_in_blue()
500       else :  self.node_selected[0].update_plusieurs_node_label_in_blue(self.node_selected)
501       self.QWParent.edit="copier"
502       self.QWParent.noeud_a_editer = self.node_selected
503
504     #------------------------#
505     def handleEditPaste(self):
506     #------------------------#
507       """
508       Lance la copie de l'objet place dans self.QWParent.noeud_a_editer
509       Ne permet que la copie d'objets de type Commande ou MCF
510       """
511       self.chercheNoeudSelectionne()
512       if (not(hasattr(self.QWParent,'noeud_a_editer'))) or len(self.QWParent.noeud_a_editer)==0:
513           QMessageBox.information( self,
514                       tr("Copie impossible"),
515                       tr("Veuillez selectionner un objet a copier"))
516           return
517       if len(self.node_selected) != 1 :
518           QMessageBox.information( self,
519                       tr("Copie impossible"),
520                       tr("Veuillez selectionner un seul objet : la copie se fera apres le noeud selectionne"))
521           return
522
523       if len(self.QWParent.noeud_a_editer)!=1:
524          self.handleEditPasteMultiple()
525          return
526
527       noeudOuColler=self.node_selected[0]
528       pos='after'
529       if noeudOuColler == self.tree.racine:
530          indexNoeudOuColler=0
531          pos='before'
532       else :
533          indexNoeudOuColler=noeudOuColler.treeParent.children.index(noeudOuColler)
534
535       try :
536        noeudACopier=self.QWParent.noeud_a_editer[0]
537        indexNoeudACopier=noeudACopier.treeParent.children.index(noeudACopier)
538       except :
539        QMessageBox.information( self, tr("Copie impossible"), tr("Aucun Objet n a ete copie ou coupe"))
540        return
541
542       if (self.QWParent.edit != "couper"):
543         try:
544            if noeudOuColler == self.tree.racine :
545               child=noeudOuColler.doPastePremier(noeudACopier)
546            else :
547               child=noeudACopier.doPaste(noeudOuColler,pos)
548            if child==None or child==0:
549                QMessageBox.critical( self,tr( "Copie refusee"),tr('Eficas n a pas reussi a copier l objet'))
550                self.message = ''
551                self.affiche_infos("Copie refusee",Qt.red)
552            if noeudACopier.treeParent.editor != noeudOuColler.treeParent.editor:
553                try :
554                  nom=noeudACopier.item.sd.nom
555                  child.item.nomme_sd(nom)
556                except :
557                  pass
558            return
559            self.init_modif()
560            child.select()
561         except  :
562            traceback.print_exc()
563            QMessageBox.critical( self,tr( "Copie refusee"),tr('Copie refusee pour ce type d objet'))
564            self.message = ''
565            self.affiche_infos("Copie refusee",Qt.red)
566            return
567
568       # il faut declarer le JDCDisplay_courant modifie
569       # suppression eventuelle du noeud selectionne
570       # si possible on renomme l objet comme le noeud couper
571
572       if (self.QWParent.edit == "couper"):
573          #try :
574          if noeudACopier.treeParent.editor != noeudOuColler.treeParent.editor:
575            QMessageBox.critical( self, tr("Deplacement refuse"),tr('Deplacement refuse entre 2 fichiers. Seule la copie est autorisee '))
576
577          #if 1:
578          try :
579             indexNoeudACopier=noeudACopier.treeParent.children.index(noeudACopier)
580             noeudACopier.treeParent.item.deplaceEntite(indexNoeudACopier,indexNoeudOuColler,pos)
581             noeudACopier.treeParent.build_children()
582
583          #else:
584          except:
585             pass
586          self.QWParent.noeud_a_editer=[]
587
588       # on rend la copie a nouveau possible en liberant le flag edit
589       self.QWParent.edit="copier"
590       noeudACopier.select()
591
592     #----------------------------------#
593     def handleDeplaceMultiple(self):
594     #----------------------------------#
595        pass
596
597     #----------------------------------#
598     def handleEditPasteMultiple(self):
599     #----------------------------------#
600
601     # On ne garde que les niveaux "Etape"
602     # On insere dans l'ordre du JDC
603      listeNoeudsACouper=[]
604      listeIndex=[]
605      listeChild=[]
606      listeItem=[]
607      from InterfaceQT4 import compojdc
608      noeudOuColler=self.node_selected[0]
609      if not (isinstance(noeudOuColler.treeParent, compojdc.Node)):
610         QMessageBox.information( self,
611                   tr("Copie impossible a cet endroit",),
612                   tr("Veuillez selectionner une commande, un parametre, un commentaire ou une macro"))
613         return
614      indexNoeudOuColler=noeudOuColler.treeParent.children.index(noeudOuColler)
615
616      for noeud in self.QWParent.noeud_a_editer :
617         if not (isinstance(noeud.treeParent, compojdc.Node)): continue
618         indexInTree=noeud.treeParent.children.index(noeud)
619         indice = 0
620         for index in listeIndex:
621             if index < indexInTree : indice = indice +1
622         listeIndex.insert(indice, indexInTree)
623         listeNoeudsACouper.insert(indice, noeud)
624
625      noeudJdc=noeudOuColler.treeParent
626      dejaCrees=0
627      # on les cree a l'envers parcequ'on ajoute a NoeudOuColler
628      listeIndex.reverse()
629      for index in listeIndex:
630          indexTravail=index
631          if indexNoeudOuColler < index:
632             indexTravail=indexTravail+dejaCrees
633          noeudOuColler=noeudJdc.children[indexNoeudOuColler]
634          noeud=noeudJdc.children[indexTravail]
635          child=noeud.doPaste(noeudOuColler)
636          listeChild.append(child)
637          dejaCrees=dejaCrees+1
638
639      self.QWParent.noeud_a_editer = []
640      for i in range(len(listeIndex)):
641         noeud=noeudJdc.children[indexNoeudOuColler+1+i]
642         self.QWParent.noeud_a_editer.append(noeud)
643
644      listeASupprimer=[]
645      if self.QWParent.edit !="couper" : return
646
647      for index in listeIndex:
648          indexTravail=index
649          if indexNoeudOuColler < index:
650             indexTravail=indexTravail+(len(listeIndex))
651          noeud=noeudJdc.children[indexTravail]
652
653          listeItem.append(noeud.item)
654          listeASupprimer.append(noeud)
655
656      for i in range(len(listeChild)):
657          self.tree.item.suppitem(listeItem[i])
658          listeChild[i].item.update(listeItem[i])
659
660      self.QWParent.noeud_a_editer = []
661
662
663     #---------------------#
664     def getFileName(self):
665     #---------------------#
666       return self.fichier
667
668     #---------------------------#
669     def get_file_variable(self) :
670     #---------------------------#
671      titre = tr("Choix d'un fichier XML")
672      texte = tr("Le fichier contient une commande MODEL\n")
673      texte = texte+tr('Donnez le nom du fichier XML qui contient la description des variables')
674      QMessageBox.information( self, titre,tr(texte))
675
676      fichier = QFileDialog.getOpenFileName(self.appliEficas,
677                    tr('Ouvrir Fichier'),
678                    self.appliEficas.CONFIGURATION.savedir,
679                    self.appliEficas.trUtf8('Wrapper Files (*.xml);;''All Files (*)'))
680      return  fichier
681
682     #----------------------------------#
683     def writeFile(self, fn, txt = None):
684     #----------------------------------#
685         """
686         Public slot to write the text to a file.
687
688         @param fn filename to write to (string or QString)
689         @return flag indicating success
690         """
691
692         fn = unicode(fn)
693
694         if txt == None :
695             txt = self.get_text_JDC(self.format)
696             eol = '\n'
697             if len(txt) >= len(eol):
698                if txt[-len(eol):] != eol:
699                   txt += eol
700             else:
701                 txt += eol
702             txt=self.ajoutVersionCataDsJDC(txt)
703             checksum=self.get_checksum(txt)
704             txt=txt+checksum
705         try:
706             f = open(fn, 'wb')
707             f.write(txt)
708             f.close()
709             return 1
710         except IOError, why:
711             QMessageBox.critical(self, self.trUtf8('Save File'),
712                 self.trUtf8('The file <b>%1</b> could not be saved.<br>Reason: %2')
713                     .arg(unicode(fn)).arg(str(why)))
714             return 0
715
716     #-------------------------------------#
717     def get_text_JDC(self,format,pourRun=0):
718     #-------------------------------------#
719       if self.code == "MAP" and not(generator.plugins.has_key(format)): format = "MAP"
720       if generator.plugins.has_key(format):
721          # Le generateur existe on l'utilise
722          self.generator=generator.plugins[format]()
723          try :
724             jdc_formate=self.generator.gener(self.jdc,format='beautifie',config=self.appliEficas.CONFIGURATION)
725             if pourRun : jdc_formate=self.generator.textePourRun
726          except ValueError,e:
727             QMessageBox.critical(self, tr("Erreur a la generation"),str(e))
728          if not self.generator.cr.estvide():
729             self.affiche_infos(tr("Erreur a la generation"),Qt.red)
730             QMessageBox.critical( self, tr("Erreur a la generation"),tr("EFICAS ne sait pas convertir ce JDC"))
731             return ""
732          else:
733             return jdc_formate
734       else:
735          # Il n'existe pas c'est une erreur
736          self.affiche_infos(tr("Format %s non reconnu" , self.format),Qt.red)
737          QMessageBox.critical( self, "Format  non reconnu" ,tr("EFICAS ne sait pas convertir le JDC selon le format "+ self.format))
738          return ""
739
740     #------------#
741     def run(self):
742     #------------#
743       fonction="run"+self.code
744       if fonction in JDCEditor.__dict__.keys(): apply(JDCEditor.__dict__[fonction],(self,))
745
746     #------------#
747     def saveRun(self):
748     #------------#
749       fonction="saveRun"+self.code
750       if fonction in JDCEditor.__dict__.keys(): apply(JDCEditor.__dict__[fonction],(self,))
751
752     #---------------#
753     def runMAP(self):
754     #---------------#
755
756       if not(self.jdc.isvalid()):
757          QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution MAP"))
758          return
759       if len(self.jdc.etapes) != 1 :
760          QMessageBox.critical( self, tr("Execution impossible "),tr("le JDC doit contenir un et un seul composant"))
761          return
762       if self.modified or self.fichier==None  :
763          self.fichierMapInput = self.__generateTempFilename(prefix = "map_run", suffix = ".map")
764          texte=self.get_text_JDC("MAP")
765          self.writeFile( self.fichierMapInput, txt = texte)
766       else :
767          self.fichierMapInput=self.fichier
768       composant=self.jdc.etapes[0].nom.lower()[0:-5]
769
770
771       # :TRICKY: to determine if a component requires SALOME, loads the component from Eficas catalog
772       # then instantiate corresponding class and call getUseSalome() method
773       try:
774           from mapengine.spec import factory
775           mapComponent = factory.new(composant)[0]
776
777           command = "map"
778           if mapComponent.getUseSalome():
779               command += " -r sappli"
780           textePython=(command + " run -n "+composant +" -i "+self.fichierMapInput)
781
782           #textePython="ls -l"
783           self._viewTextExecute( textePython,"map_run",".sh")
784           try:
785              commande="rm  "+self.fichierMapInput
786              os.system(commande)
787           except :
788              pass
789       except Exception, e:
790           print traceback.print_exc()
791
792     #-------------------#
793     def runZCRACKS(self):
794     #-------------------#
795       if not(self.jdc.isvalid()):
796          QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution "))
797          return
798       if self.modified or self.fichier==None  :
799       #if 1:
800          self.fichierZcracksInput = self.__generateTempFilename(prefix = "zcracks_run", suffix = ".z7p")
801          texte=self.get_text_JDC("ZCRACKS",pourRun=1)
802          self.writeFile( self.fichierZcracksInput, txt = texte)
803       else :
804          self.fichierZcracksInput=self.fichier
805       try :
806           #commande ="Zrun -zp "
807           commande="more "
808           textePython=(commande + self.fichierZcracksInput)
809           self._viewTextExecute( textePython,"run_zcracks",".sh")
810       except Exception, e:
811           print traceback.print_exc()
812
813     #-------------------#
814     def runCARMELCND(self):
815     #-------------------#
816       #if not(self.jdc.isvalid()):
817       #   QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution "))
818       #   return
819       if self.modified or self.fichier==None  :
820          QMessageBox.critical( self, tr( "Execution impossible "),tr("Sauvegarder SVP avant l'execution "))
821          return
822       if not hasattr(self,'generator'): texte=self.get_text_JDC(self.format)
823       from PrepareRunCarmel import prepareRunCarmel
824       fichierGenerique=os.path.basename(self.fichier).split(".")[0]
825       repMed=os.path.dirname(self.fichier)
826       repExeCarmel=self.generator.get_repExeCarmel()
827       textePython=prepareRunCarmel(repExeCarmel,repMed,fichierGenerique)
828       nomFichier = self.__generateTempFilename("carmel_run", suffix = ".sh")
829       f=open(nomFichier,'w')
830       f.write(textePython)
831       f.close()
832       commande="xterm -e sh "+nomFichier +"\n"
833       os.system(commande)
834       #try :
835       #    self._viewTextExecute( textePython,"carmel_run",".sh")
836       #except Exception, e:
837       #    print traceback.print_exc()
838
839     #-------------------#
840     def runCarmelCS(self):
841     #-------------------#
842       try :
843           commande="runSession pilotyacsCS.py"
844           os.system(commande)
845       except Exception, e:
846           print traceback.print_exc()
847
848     #-----------------------------------------------------#
849     def determineNomFichier(self,path,extension):
850     #-----------------------------------------------------#
851       if DictExtensions.has_key(self.appli.code) :
852          chaine1="JDC (*"+DictExtensions[self.appli.code]+");;"
853          extensions= self.trUtf8(chaine1+ "All Files (*)")
854       else :
855          extensions= self.trUtf8("JDC (*.comm);;" "All Files (*)")
856
857       if self.appli.code == "MAP" :
858          extensions = extensions + ";; Run (*.input);;"
859
860       fn = QFileDialog.getSaveFileName( self,
861              tr("sauvegarde"), path,
862              extensions,None,
863              QFileDialog.DontConfirmOverwrite)
864       if fn.isNull(): return (0, None)
865       ext = QFileInfo(fn).suffix()
866       if ext.isEmpty(): fn.append(extension)
867
868       if QFileInfo(fn).exists():
869            abort = QMessageBox.warning(self,
870                    tr("Sauvegarde du Fichier"),
871                    tr("Le fichier <b>%s</b> existe deja.",str(fn)),
872                    tr("&Ecraser"),
873                    self.trUtf8("&Abandonner"))
874            if abort == 1 :  return (0, "")
875       return (1,fn)
876
877     #-----------------#
878     def saveRunMAP(self):
879     #-----------------#
880         extension=".input"
881         if not(self.jdc.isvalid()):
882            QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
883                                 tr("Un JdC valide est necessaire pour creer un .input")
884                                  )
885            return
886         try :
887           composant=self.jdc.etapes[0].nom.lower()[0:-5]
888         except :
889            QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
890                                 tr("Choix du composant obligatoire")
891                                  )
892            return
893         if hasattr(self.CONFIGURATION, "savedir"): path=self.CONFIGURATION.savedir
894         else : path=os.environ['HOME']
895
896         monNomFichier=""
897         if self.fichier is not None and self.fichier != "" :
898              maBase=str(QFileInfo(self.fichier).baseName())+".input"
899              monPath=str(QFileInfo(self.fichier).absolutePath())
900              monNomFichier=os.path.join(monPath,maBase)
901         elif hasattr(self,'monNomFichierInput'):
902             monNomFichier=self.monNomFichierInput
903
904
905         monDialog=QFileDialog(self.appliEficas)
906         monDialog.setDirectory (path)
907         monDialog.setWindowTitle ("Save")
908
909         for c in monDialog.children():
910             if isinstance(c,QDialogButtonBox):
911                for b in c.children():
912                   if isinstance(b,QPushButton):
913                      avant=b.text()
914                      if avant.toLatin1()=="&Open":
915                         b.setText("Save")
916         mesFiltres=QStringList()
917         mesFiltres << "input Map (*.input)" << "All Files (*)"
918         monDialog.setNameFilters(mesFiltres)
919         if monNomFichier!="" : monDialog.selectFile(monNomFichier)
920         BOk=monDialog.exec_()
921         if BOk==0: return
922         fn=str(monDialog.selectedFiles()[0].toLatin1())
923         if fn == "" or fn == None : return
924         if not fn.endswith(".input"):
925             fn += ".input"
926         self.monNomFichierInput=fn
927
928         if not hasattr(self, 'fichierMapInput') or not self.fichierMapInput or not os.path.exists(self.fichierMapInput):
929             self.fichierMapInput = self.__generateTempFilename(prefix = "map_run", suffix = ".map")
930             texte=self.get_text_JDC("MAP")
931             self.writeFile( self.fichierMapInput, txt = texte)
932
933         cmd = ("map gen -t dat -n " + composant + " -i " + self.fichierMapInput + " -o " + fn)
934         p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
935         (output, err) = p.communicate()
936
937
938     #-----------------------------------------#
939     def cherche_Groupes(self):
940     #-----------------------------------------#
941         listeMA,listeNO=self.get_text_JDC("GroupMA")
942         return listeMA,listeNO
943
944     #-----------------------------------------#
945     def cherche_Dico(self):
946     #-----------------------------------------#
947         dicoCourant={}
948         format =  self.appliEficas.format_fichier
949         if generator.plugins.has_key(format):
950            # Le generateur existe on l'utilise
951            self.generator=generator.plugins[format]()
952            jdc_formate=self.generator.gener(self.jdc,format='beautifie',config=self.appliEficas.CONFIGURATION)
953            dicoCourant=self.generator.dico
954         return dicoCourant
955
956          
957
958     #-----------------------------------------#
959     def handleAjoutGroup(self,listeGroup):
960     #-----------------------------------------#
961         try :
962         #if 1:
963            from ajoutGroupe import handleAjoutGroupFiltre
964            #print listeGroup
965            handleAjoutGroupFiltre(self,listeGroup)
966            #print "apres handleAjoutGroupFiltre"
967         except :
968         #else :
969            pass
970
971     #-----------------------------------------#
972     def saveFile(self, path = None, saveas= 0):
973     #-----------------------------------------#
974         """
975         Public slot to save the text to a file.
976
977         @param path directory to save the file in (string or QString)
978         @return tuple of two values (boolean, string) giving a success indicator and
979             the name of the saved file
980         """
981
982         #self.modified=1
983         if not self.modified and not saveas:
984             return (0, None)      # do nothing if text wasn't changed
985
986         extension='.py'
987         if DictExtensions.has_key(self.appli.code) :
988            extension=DictExtensions[self.appli.code]
989         else :
990            extension='.comm'
991
992         newName = None
993         fn = self.fichier
994         if self.fichier is None or saveas:
995           if path is None:
996              path=self.CONFIGURATION.savedir
997           bOK, fn=self.determineNomFichier(path,extension)
998           if bOK == 0 : return (0, None)
999           if fn == None : return (0, None)
1000           if fn.isNull(): return (0, None)
1001
1002           ulfile = os.path.abspath(unicode(fn))
1003           self.appliEficas.CONFIGURATION.savedir=os.path.split(ulfile)[0]
1004           fn = unicode(QDir.convertSeparators(fn))
1005           newName = fn
1006
1007         if not (self.writeFile(fn)): return (0, None)
1008         self.fichier = fn
1009         self.modified  = False
1010         if self.fileInfo is None or saveas:
1011            self.fileInfo = QFileInfo(self.fichier)
1012            self.fileInfo.setCaching(0)
1013         self.lastModified = self.fileInfo.lastModified()
1014         if newName is not None:
1015            self.appliEficas.addToRecentList(newName)
1016            self.tree.racine.item.getObject().nom=os.path.basename(newName)
1017            self.tree.racine.update_node_label()
1018
1019         if self.jdc.isvalid() != 0 and hasattr(self.generator, "writeDefault"):
1020             self.generator.writeDefault(fn)
1021
1022         if self.salome :
1023                self.appliEficas.addJdcInSalome( self.fichier)
1024         self.modified = 0
1025         nouveauTitre=self.titre+"              "+str(os.path.basename(self.fichier))
1026         self.appliEficas.setWindowTitle(nouveauTitre)
1027
1028         return (1, self.fichier)
1029 #
1030     #----------------------------------------------#
1031     def saveFileAs(self, path = None,fileName=None):
1032     #----------------------------------------------#
1033         """
1034         Public slot to save a file with a new name.
1035
1036         @param path directory to save the file in (string or QString)
1037         @return tuple of two values (boolean, string) giving a success indicator and
1038             the name of the saved file
1039         """
1040         if fileName != None :
1041            self.fichier = fileName
1042            return self.saveFile()
1043         return self.saveFile(path,1)
1044
1045
1046
1047     #---------------------------------------------#
1048     def get_file(self,unite=None,fic_origine = ''):
1049     #---------------------------------------------#
1050     # appele par I_JDC
1051         ulfile  = None
1052         jdcText = ""
1053
1054         titre  = ""
1055
1056         if unite :
1057             titre = tr("Choix unite %d ", unite)
1058             texte = tr("Le fichier %s contient une commande INCLUDE \n",  str(fic_origine)) +"\n"
1059             texte = texte+ tr("Donnez le nom du fichier correspondant a l unite logique ") + repr(unite)
1060             labeltexte = tr('Fichier pour unite ') + repr( unite)
1061         else:
1062             titre = tr("Choix d'un fichier de poursuite")
1063             texte = tr("Le fichier %s contient une commande POURSUITE\n", fic_origine)
1064             texte = texte+tr('Donnez le nom du fichier dont vous \n voulez faire une poursuite')
1065
1066         QMessageBox.information( self, titre,QString.fromUtf8(texte))
1067         fn = QFileDialog.getOpenFileName(self.appliEficas,
1068                    titre,
1069                    self.appliEficas.CONFIGURATION.savedir)
1070
1071         if fn.isNull():
1072         # ce retour est impose par le get_file d'I_JDC
1073            return None," "
1074
1075         ulfile = os.path.abspath(unicode(fn))
1076         self.appliEficas.CONFIGURATION.savedir=os.path.split(ulfile)[0]
1077
1078         # On utilise le convertisseur defini par format_fichier
1079         source=self.get_source(ulfile)
1080         if source:
1081             # On a reussia convertir le fichier self.ulfile
1082             jdcText = source
1083         else:
1084             # Une erreur a ete rencontree
1085             jdcText = ''
1086         return ulfile, jdcText
1087
1088     #-------------------------------#
1089     def updateJdc(self, itemApres,texte):
1090     #--------------------------------#
1091         monItem=itemApres
1092         etape=monItem.item.object
1093
1094         CONTEXT.set_current_step(etape)
1095         etape.build_includeInclude(texte)
1096         self.tree.racine.build_children()
1097
1098
1099
1100
1101     #-------------------------------------#
1102     def ajoutVersionCataDsJDC(self,txt):
1103     #-------------------------------------#
1104         if not hasattr(self.readercata.cata[0],'VERSION_CATALOGUE'): return txt
1105         ligneVersion="#VERSION_CATALOGUE:"+self.readercata.cata[0].VERSION_CATALOGUE+":FIN VERSION_CATALOGUE\n"
1106         texte=txt+ligneVersion
1107         return texte
1108
1109     #-------------------------------------#
1110     def verifieVersionCataDuJDC(self,text):
1111     #-------------------------------------#
1112         memeVersion=False
1113         indexDeb=text.find("#VERSION_CATALOGUE:")
1114         indexFin=text.find(":FIN VERSION_CATALOGUE")
1115         if indexDeb < 0 :
1116            self.versionCataDuJDC="sans"
1117            textJDC=text
1118         else :
1119            self.versionCataDuJDC=text[indexDeb+19:indexFin]
1120            textJDC=text[0:indexDeb]+text[indexFin+23:-1]
1121
1122         self.versionCata="sans"
1123         if hasattr(self.readercata.cata[0],'VERSION_CATALOGUE'): self.versionCata=self.readercata.cata[0].VERSION_CATALOGUE
1124
1125         if self.versionCata==self.versionCataDuJDC : memeVersion=True
1126         return memeVersion,textJDC
1127
1128     #-------------------------------#
1129     def traduitCatalogue(self,texte):
1130     #-------------------------------#
1131         nomTraducteur="traduit"+self.readercata.code+self.versionCataDuJDC+"To"+self.versionCata
1132         sys.path.append(os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"../Traducteur")))
1133         try :
1134             traducteur=__import__(nomTraducteur)
1135             monTraducteur=traducteur.MonTraducteur(texte)
1136             nouveauTexte=monTraducteur.traduit()
1137             return nouveauTexte
1138         except :
1139             return texte
1140
1141
1142     #------------------------------#
1143     def verifieCHECKSUM(self,text):
1144     #------------------------------#
1145         indexDeb=text.find("#CHECKSUM:")
1146         if indexDeb < 0 :
1147            return 1, text
1148         indexFin=text.find(":FIN CHECKSUM")
1149         checkAvant=text[indexDeb:indexFin+13]
1150         textJDC=text[0:indexDeb]+text[indexFin+13:-1]
1151         checksum=self.get_checksum(textJDC)
1152         pareil=(checkAvant==checksum)
1153         return pareil, textJDC
1154
1155     #---------------------------#
1156     def get_checksum(self,texte):
1157     #---------------------------#
1158         newtexte=texte.replace('"','\\"')
1159         commande='echo "'+newtexte+'"|md5sum'
1160         a=os.popen(commande)
1161         checksum=a.read()
1162         a.close()
1163         ligne="#CHECKSUM:"+checksum[0:-1]+":FIN CHECKSUM"
1164         return ligne
1165
1166
1167     #---------------------------#
1168     def _newTELEMAC(self):
1169     #---------------------------#
1170         texte="INITIALIZATION();TIDE_PARAMETERS();INITIAL_STATE();NUMERICAL_PARAMETERS();PHYSICAL_PARAMETERS()"
1171         return texte
1172
1173     #---------------------------#
1174
1175     #---------------------------#
1176     def _newZCRACKS(self):
1177     #---------------------------#
1178         texte="MAILLAGES();REMESHING();"
1179         return texte
1180
1181     #---------------------------#
1182     def _newJDCCND(self):
1183     #---------------------------#
1184       extensions=tr('Fichiers Med (*.med);;''Tous les Fichiers (*)')
1185       
1186       #if self.salome == 0 :
1187       QMessageBox.information( self,
1188                       tr("Fichier Med"),
1189                       tr("Veuillez selectionner un fichier Med"))
1190       QSfichier = QFileDialog.getOpenFileName(self.appliEficas,
1191                         caption='Fichier Med',
1192                         filter=extensions)
1193       self.fichierMED=str(QSfichier.toLatin1())
1194       from acquiertGroupes import getGroupes
1195       erreur,self.listeGroupes,self.nomMaillage,self.dicoCoord=getGroupes(self.fichierMED)
1196       if erreur != "" : print "a traiter"
1197       texteComm="COMMENTAIRE(u'Cree - fichier : "+self.fichierMED +" - Nom Maillage : "+self.nomMaillage+"');\nPARAMETRES()\n"
1198       texteSources=""
1199       texteCond=""
1200       texteNoCond=""
1201       texteVcut=""
1202       texteZs=""
1203       for groupe in self.listeGroupes :
1204           if groupe[0:8]=='CURRENT_': 
1205              texteSources +=groupe[8:]+"=SOURCE("
1206              texteSources +="VecteurDirecteur=(1.0,2.0,3.0,),);\n"
1207           if groupe[0:5]=='COND_':    texteCond    +=groupe[5:]+"=CONDUCTEUR();\n"
1208           if groupe[0:7]=='NOCOND_':  texteNoCond  +=groupe[7:]+"=NOCOND();\n"
1209           if groupe[0:5]=='VCUT_':    texteVcut    +='V_'+groupe[5:]+"=VCUT();\n"
1210           if groupe[0:3]=='ZS_':      texteZs      +=groupe[3:]+"=ZS();\n"
1211       texte=texteComm+texteSources+texteCond+texteNoCond+texteVcut+texteZs
1212       self.newTexteCND=texte
1213       self.modified=1
1214       return texte
1215
1216
1217     #---------------------------#
1218     def  BoutonFileSelected(self):
1219     #---------------------------#
1220
1221       QSfichier=self.openfile.selectedFiles()[0]
1222       self.fichierMED=str(QSfichier.toLatin1())
1223       from acquiertGroupes import getGroupes
1224       erreur,self.listeGroupes,self.nomMaillage=getGroupes(self.fichierMED)
1225       if erreur != "" : print "a traiter"
1226
1227     #-----------------------------
1228     def BoutonSalomePressed(self):
1229     #----------------------------
1230       Msg,self.listeGroupes=self.appliEficas.ChercheGrpMailleInSalome()
1231       self.fichierMED="A_partir_de_SMESH"
1232       self.nomMaillage="A_partir_de_SMESH"
1233       self.openfile.close()
1234
1235
1236 if __name__ == "__main__":
1237     self.code='ASTER'
1238     name='prefs_'+prefs.code
1239     prefsCode=__import__(name)
1240
1241
1242     if hasattr(prefsCode,'encoding'):
1243        # Hack pour changer le codage par defaut des strings
1244        import sys
1245        reload(sys)
1246        sys.setdefaultencoding(prefs.encoding)
1247        del sys.setdefaultencoding
1248        # Fin hack
1249
1250 #    code=options.code
1251 #
1252     app = QApplication(sys.argv)
1253     mw = JDCEditor(None,'azAster.comm')
1254     app.setMainWidget(mw)
1255     app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
1256     mw.show()
1257
1258     res = app.exec_loop()
1259     sys.exit(res)