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