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