1 # -*- coding: utf-8 -*-
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
24 from PyQt4.QtGui import *
25 from PyQt4.QtCore import *
29 import convert,generator
30 from Editeur import session
31 from Editeur import comploader
32 from Editeur import Objecttreeitem
37 DictExtensions= {"MAP" : ".map"}
41 class JDCEditor(QSplitter):
42 # -------------------------- #
47 def __init__ (self,appli,fichier = None, jdc = None, QWParent=None, units = None, include=0 , vm=None):
48 #----------------------------------------------------------------------------------------------------------#
50 #print "fichier", fichier,"jdc",jdc,"units",units,"include",include
51 QSplitter.__init__(self, QWParent)
52 self.appliEficas = appli
53 self.appli = appli #---- attendu par IHM
55 self.fichier = fichier
57 self.QWParent = QWParent
60 VERSION_CODE = session.d_env.cata
62 self.salome = self.appliEficas.salome
63 self.format = self.appliEficas.format_fichier
66 print "dans JDC pas d appli ????????"
68 self.code = self.appliEficas.CONFIGURATION.code
69 self.version_code = VERSION_CODE
70 self.titre=self.appliEficas.VERSION_EFICAS + ' pour '+ self.code
73 self.liste_simp_reel=[]
77 nameConf='configuration_'+prefs.code
78 configuration=__import__(nameConf)
79 self.CONFIGURATION = self.appliEficas.CONFIGURATION
80 self.CONFIGStyle = self.appliEficas.CONFIGStyle
83 self.CONFIGURATION.generator_module
84 _module = __import__(self.CONFIGURATION.generator_module)
85 info = _module.entryPoint()
86 generator.plugins.addEntryPoint(info)
91 self.CONFIGURATION.convert_module
92 _module = __import__(self.CONFIGURATION.convert_module)
93 info = _module.entryPoint()
94 convert.plugins.addEntryPoint(info)
99 if hasattr(self.appliEficas,"statusBar"):
100 self.sb = self.appliEficas.statusBar()
103 self.lastModified = 0
105 self.modified = False
106 self.isReadOnly = False
108 self.node_selected = None
111 #if not hasattr( readercata, 'reader' ) :
112 # readercata.reader = readercata.READERCATA( self, self.appliEficas )
113 #self.readercata = readercata.reader
114 if not hasattr ( self.appliEficas, 'readercata'):
115 self.readercata = readercata.READERCATA( self, self.appliEficas )
116 self.appliEficas.readercata=self.readercata
118 self.readercata=self.appliEficas.readercata
119 if self.readercata.fic_cata == None : return #Sortie Salome
120 self.Commandes_Ordre_Catalogue =self.readercata.Commandes_Ordre_Catalogue
122 #------- construction du jdc --------------
125 self.mode_nouv_commande=self.readercata.mode_nouv_commande
128 if self.fichier is not None: # fichier jdc fourni
129 self.fileInfo = QFileInfo(self.fichier)
130 self.fileInfo.setCaching(0)
132 self.jdc = self.readFile(self.fichier)
135 if units is not None:
136 self.jdc.recorded_units=units
137 self.jdc.old_recorded_units=units
139 if not self.jdc: # nouveau jdc
141 self.jdc = self._newJDC(units=units)
143 self.jdc = self._newJDCInclude(units=units)
147 self.jdc.appli = self
151 txt_exception = self.jdc.cr.get_mess_exception()
154 qApp.restoreOverrideCursor()
155 self.affiche_infos("Erreur fatale au chargement de %s" %fichier,Qt.red)
156 QMessageBox.critical( self, "Erreur fatale au chargement d'un fichier", txt_exception)
158 comploader.charger_composants("QT")
159 jdc_item=Objecttreeitem.make_objecttreeitem( self, "nom", self.jdc )
161 if (not self.jdc.isvalid()) and (not nouveau) :
162 self.viewJdcRapport()
164 self.tree = browser.JDCTree( jdc_item, self )
166 #--------------------------------#
167 def _newJDC( self ,units = None):
168 #--------------------------------#
170 Initialise un nouveau JDC vierge
172 CONTEXT.unset_current_step()
173 jdc=self.readercata.cata[0].JdC( procedure="",
175 cata=self.readercata.cata,
176 cata_ord_dico=self.readercata.cata_ordonne_dico,
177 rep_mat=self.CONFIGURATION.rep_mat
179 if units is not None:
180 jdc.recorded_units=units
181 jdc.old_recorded_units=units
185 #--------------------------------#
186 def _newJDCInclude( self ,units = None):
187 #--------------------------------#
189 Initialise un nouveau JDC vierge
191 import Extensions.jdc_include
192 JdC_aux=Extensions.jdc_include.JdC_include
193 CONTEXT.unset_current_step()
195 jaux=self.readercata.cata[0].JdC( procedure="",
197 cata=self.readercata.cata,
198 cata_ord_dico=self.readercata.cata_ordonne_dico,
199 rep_mat=self.CONFIGURATION.rep_mat,
203 J=JdC_aux( procedure="",
205 cata=self.readercata.cata,
206 cata_ord_dico=self.readercata.cata_ordonne_dico,
208 rep_mat=self.CONFIGURATION.rep_mat,
211 if units is not None:
212 J.recorded_units=units
213 J.old_recorded_units=units
216 #-----------------------#
217 def readFile(self, fn):
218 #--------------------------------#
220 Public slot to read the text from a file.
221 @param fn filename to read from (string or QString)
225 # ------------------------------------------------------------------------------------
227 # ------------------------------------------------------------------------------------
229 jdcName=os.path.basename(fn)
230 # Il faut convertir le contenu du fichier en fonction du format
231 if convert.plugins.has_key( self.appliEficas.format_fichier_in ):
232 # Le convertisseur existe on l'utilise
234 p=convert.plugins[self.appliEficas.format_fichier_in]()
236 text=p.convert('exec',self.appliEficas)
237 if not p.cr.estvide():
238 self.affiche_infos("Erreur à la conversion",Qt.red)
240 self.affiche_infos("Type de fichier non reconnu",Qt.red)
241 QMessageBox.critical( self, "Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
244 CONTEXT.unset_current_step()
245 jdc=self.readercata.cata[0].JdC(procedure=text,
247 cata=self.readercata.cata,
248 cata_ord_dico=self.readercata.cata_ordonne_dico,
250 rep_mat=self.CONFIGURATION.rep_mat
252 # ----------------------------------------------------
254 # ----------------------------------------------------
255 self.modified = False
257 # qApp.restoreOverrideCursor()
258 if self.fileInfo!= None :
259 self.lastModified = self.fileInfo.lastModified()
261 self.lastModified = 1
265 #-----------------------#
266 def get_source(self,file):
267 #-----------------------#
268 format=self.appliEficas.format_fichier
270 # Il faut convertir le contenu du fichier en fonction du format
271 if convert.plugins.has_key(format):
272 # Le convertisseur existe on l'utilise
273 p=convert.plugins[format]()
275 text=p.convert('execnoparseur')
276 if not p.cr.estvide():
277 self.affiche_infos("Erreur a la conversion",Qt.red)
280 # Il n'existe pas c'est une erreur
281 self.affiche_infos("Type de fichier non reconnu",Qt.red)
282 QMessageBox.critical( self, "Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
285 #----------------------------------------------#
286 def _viewText(self, txt, caption = "FILE_VIEWER"):
287 #----------------------------------------------#
288 w = qtCommun.ViewText( self.QWParent )
289 w.setWindowTitle( caption )
293 #-----------------------#
294 def viewJdcSource(self):
295 #-----------------------#
296 format = self.appliEficas.format_fichier
297 f=open(self.fichier,'r')
300 self._viewText(texteSource, "JDC_SOURCE")
302 #-----------------------#
304 #-----------------------#
305 format = self.appliEficas.format_fichier
306 strSource = str( self.get_text_JDC(format) )
307 self._viewText(strSource, "JDC_RESULTAT")
309 #-----------------------#
310 def viewJdcRapport(self):
311 #-----------------------#
312 strRapport = str( self.jdc.report() )
313 self._viewText(strRapport, "JDC_RAPPORT")
319 Public method called by the viewmanager to finally get rid of us.
325 #----------------------------------------------#
326 def affiche_infos(self,message,couleur=Qt.black):
327 #----------------------------------------------#
329 mapalette=self.sb.palette()
330 from PyQt4.QtGui import QPalette
331 mapalette.setColor( QPalette.WindowText, couleur )
332 self.sb.setPalette( mapalette );
333 self.sb.showMessage(QString.fromUtf8(message))#,2000)
335 #------------------------------#
336 def affiche_alerte(self,titre,message):
337 #------------------------------#
338 # appele par I_MACRO_ETAPE
339 QMessageBox.information( self, titre, message)
341 #-------------------#
342 def init_modif(self):
343 #-------------------#
345 Met l'attribut modified a 'o' : utilise par Eficas pour savoir
346 si un JDC doit etre sauvegarde avant destruction ou non
350 #---------------------------------------#
351 def chercheNoeudSelectionne(self,copie=1):
352 #---------------------------------------#
354 appele par Cut et Copy pour positionner self.node_selected
356 self.node_selected=None
357 if len(self.tree.selectedItems()) == 0 : return
358 if len(self.tree.selectedItems()) != 1 :
359 QMessageBox.information( self,
361 "Cette version d'EFICAS permet uniquement la copie d un seul objet")
363 self.node_selected=self.tree.selectedItems()[0]
364 if copie == 0 : return
367 #---------------------#
368 def handleSupprimer(self):
369 #---------------------#
370 #print "handleSupprimer"
371 self.chercheNoeudSelectionne()
372 self.node_selected.delete()
374 #---------------------#
375 def handleEditCut(self):
376 #---------------------#
378 Stocke dans Eficas.noeud_a_editer le noeud à couper
380 #print "handleEditCut"
381 self.chercheNoeudSelectionne()
382 self.QWParent.edit="couper"
383 self.QWParent.noeud_a_editer = self.node_selected
385 #-----------------------#
386 def handleEditCopy(self):
387 #-----------------------#
389 Stocke dans Eficas.noeud_a_editer le noeud a copier
391 #print "handleEditCut"
392 self.chercheNoeudSelectionne()
393 self.QWParent.edit="copier"
394 self.QWParent.noeud_a_editer = self.node_selected
396 #------------------------#
397 def handleEditPaste(self):
398 #------------------------#
400 Lance la copie de l'objet place dans self.QWParent.noeud_a_editer
401 Ne permet que la copie d'objets de type Commande ou MCF
403 #print "handleEditPaste"
404 self.chercheNoeudSelectionne()
406 index_noeud_a_couper=self.QWParent.noeud_a_editer.treeParent.children.index(self.QWParent.noeud_a_editer)
408 QMessageBox.information( self,
410 "Aucun Objet n a ete copie ou coupe ")
414 child=self.QWParent.noeud_a_editer.doPaste(self.node_selected)
416 traceback.print_exc()
417 QMessageBox.information( self,
419 "Copie refusee pour ce type d objet a cet endroit")
421 self.affiche_infos("Copie refusée")
424 if child == 0 or child == None:
425 QMessageBox.critical( self, "Copie refusee",'Copie refusee pour ce type d objet')
427 self.affiche_infos("Copie refusée",Qt.red)
430 # il faut declarer le JDCDisplay_courant modifie
432 # suppression eventuelle du noeud selectionne
433 # si possible on renomme l objet comme le noeud couper
435 if self.QWParent.edit == "couper":
436 index_ajoute=child.treeParent.children.index(child)
437 if index_ajoute <= index_noeud_a_couper :
438 index_noeud_a_couper=index_noeud_a_couper + 1
439 item=self.QWParent.noeud_a_editer.item
440 noeud_a_supprimer=self.QWParent.noeud_a_editer.treeParent.children[index_noeud_a_couper]
441 noeud_a_supprimer.delete()
442 child.item.update(item)
443 #test,mess = child.item.nomme_sd(nom)
446 # on rend la copie a nouveau possible en liberant le flag edit
447 self.QWParent.edit="copier"
449 #---------------------#
450 def getFileName(self):
451 #---------------------#
454 #---------------------------#
455 def get_file_variable(self) :
456 #---------------------------#
457 titre = "Choix d'un fichier XML"
458 texte = "Le fichier contient une commande MODEL\n"
459 texte = texte+'Donnez le nom du fichier XML qui contient la description des variables'
460 QMessageBox.information( self, titre,texte)
462 fichier = QFileDialog.getOpenFileName(self.appliEficas,
463 self.appliEficas.trUtf8('Ouvrir Fichier'),
464 self.appliEficas.CONFIGURATION.savedir,
465 self.appliEficas.trUtf8('Wrapper Files (*.xml);;''All Files (*)'))
468 #----------------------------------#
469 def writeFile(self, fn, txt = None):
470 #----------------------------------#
472 Public slot to write the text to a file.
474 @param fn filename to write to (string or QString)
475 @return flag indicating success
481 txt = self.get_text_JDC(self.appliEficas.format_fichier)
483 if len(txt) >= len(eol):
484 if txt[-len(eol):] != eol:
494 QMessageBox.critical(self, self.trUtf8('Save File'),
495 self.trUtf8('The file <b>%1</b> could not be saved.<br>Reason: %2')
496 .arg(unicode(fn)).arg(str(why)))
499 #-----------------------------#
500 def get_text_JDC(self,format):
501 #-----------------------------#
502 if generator.plugins.has_key(format):
503 # Le generateur existe on l'utilise
504 self.generator=generator.plugins[format]()
505 jdc_formate=self.generator.gener(self.jdc,format='beautifie',config=self.appliEficas.CONFIGURATION)
506 if not self.generator.cr.estvide():
507 self.affiche_infos("Erreur à la generation",Qt.red)
508 QMessageBox.critical( self, "Erreur a la generation","EFICAS ne sait pas convertir ce JDC")
513 # Il n'existe pas c'est une erreur
514 self.affiche_infos("Format %s non reconnu" % format,Qt.red)
515 QMessageBox.critical( self, "Format "+format+" non reconnu","EFICAS ne sait pas convertir le JDC selon le format "+format)
518 #-----------------------------#
519 def run(self,execution="oui"):
520 #-----------------------------#
521 format=self.appliEficas.format_fichier
523 if generator.plugins.has_key(format):
524 # Le generateur existe on l'utilise
525 self.generator=generator.plugins[format]()
526 self.textePython =self.generator.generRUN(self.jdc,format='beautifie',config=self.appliEficas.CONFIGURATION)
527 if execution=="oui" :
528 os.system(self.textePython)
530 return self.textePython
532 #------------------------------------------------#
533 def runYACS(self,execution="oui",nomFichier=None):
534 #------------------------------------------------#
535 format=self.appliEficas.format_fichier
536 if generator.plugins.has_key(format):
537 # Le generateur existe on l'utilise
538 self.generator=generator.plugins[format]()
539 self.generator.generRUNYACS(self.jdc,format='beautifie',config=self.appliEficas.CONFIGURATION,nomFichier=nomFichier)
540 if execution=="oui" :
541 print "il faut faire le run dans Salome"
543 #-----------------------------#
545 #-----------------------------#
546 texte=self.run(execution="non")
547 path=self.CONFIGURATION.savedir
548 fn = QFileDialog.getSaveFileName( self,
549 self.trUtf8("sauvegarde"), path,
550 self.trUtf8("JDC (*.sh);;" "All Files (*)"),None,
551 QFileDialog.DontConfirmOverwrite)
552 if fn.isNull(): return
553 ext = QFileInfo(fn).suffix()
554 if ext.isEmpty(): fn.append(".xml")
556 if QFileInfo(fn).exists():
557 abort = QMessageBox.warning(self,
558 self.trUtf8("Sauvegarde du Fichier"),
559 self.trUtf8("Le fichier <b>%1</b> existe deja.").arg(fn),
560 self.trUtf8("&Ecraser"),
561 self.trUtf8("&Abandonner"))
562 if abort == 1 : return
564 fn = unicode(QDir.convertSeparators(fn))
565 self.writeFile( fn, txt = texte)
567 #-----------------------------#
569 #-----------------------------#
570 path=self.CONFIGURATION.savedir
571 fn = QFileDialog.getSaveFileName( self,
572 self.trUtf8("sauvegarde"), path,
573 self.trUtf8("JDC (*.xml);;" "All Files (*)"),None,
574 QFileDialog.DontConfirmOverwrite)
575 if fn.isNull(): return
576 ext = QFileInfo(fn).suffix()
577 if ext.isEmpty(): fn.append(".xml")
579 if QFileInfo(fn).exists():
580 abort = QMessageBox.warning(self,
581 self.trUtf8("Sauvegarde du Fichier"),
582 self.trUtf8("Le fichier <b>%1</b> existe deja.").arg(fn),
583 self.trUtf8("&Ecraser"),
584 self.trUtf8("&Abandonner"))
585 if abort == 1 : return
586 fn = unicode(QDir.convertSeparators(fn))
588 texte=self.runYACS(execution="non",nomFichier=fn)
589 #self.writeFile( fn, txt = texte)
591 #-----------------------------------------#
592 def cherche_Groupes(self):
593 #-----------------------------------------#
594 listeMA,listeNO=self.get_text_JDC("GroupMA")
595 return listeMA,listeNO
597 #-----------------------------------------#
598 def saveFile(self, path = None, saveas= 0):
599 #-----------------------------------------#
601 Public slot to save the text to a file.
603 @param path directory to save the file in (string or QString)
604 @return tuple of two values (boolean, string) giving a success indicator and
605 the name of the saved file
608 if not self.modified and not saveas:
609 return (0, None) # do nothing if text wasn't changed
612 if self.fichier is None or saveas:
614 path=self.CONFIGURATION.savedir
615 selectedFilter = QString('')
616 if DictExtensions.has_key(self.appli.code) :
617 chaine1="JDC (*"+DictExtensions[self.appli.code]+");;"
618 extensions= self.trUtf8(chaine1+ "All Files (*)")
620 extensions= self.trUtf8("JDC (*.comm);;" "All Files (*)")
621 fn = QFileDialog.getSaveFileName( self,
622 self.trUtf8("sauvegarde"), path,
624 QFileDialog.DontConfirmOverwrite)
625 if fn.isNull(): return (0, None)
626 ulfile = os.path.abspath(unicode(fn))
627 self.appliEficas.CONFIGURATION.savedir=os.path.split(ulfile)[0]
629 ext = QFileInfo(fn).suffix()
631 if DictExtensions.has_key(self.appli.code) :
632 fn.append(DictExtensions[self.appli.code])
636 if QFileInfo(fn).exists():
637 abort = QMessageBox.warning(self,
638 self.trUtf8("Sauvegarde du Fichier"),
639 self.trUtf8("Le fichier <b>%1</b> existe deja.").arg(fn),
640 self.trUtf8("&Ecraser"),
641 self.trUtf8("&Abandonner"))
642 if abort == 1 : return (0, None)
644 fn = unicode(QDir.convertSeparators(fn))
650 if self.writeFile(fn):
652 self.modified = False
653 if self.fileInfo is None or saveas:
654 self.fileInfo = QFileInfo(self.fichier)
655 self.fileInfo.setCaching(0)
656 self.lastModified = self.fileInfo.lastModified()
657 if newName is not None:
658 self.appliEficas.addToRecentList(newName)
659 self.tree.racine.item.getObject().nom=os.path.basename(newName)
660 self.tree.racine.update_node_label()
662 if self.jdc.isvalid() != 0 :
664 fileXML = fn[:fn.rfind(".")] + '.xml'
665 self.generator.writeOpenturnsXML( fileXML )
670 fileSTD = fn[:fn.rfind(".")] + '.py'
671 self.generator.writeOpenturnsSTD( fileSTD )
676 self.generator.writeDefault(fn)
681 fileCuve2DG = fn[:fn.rfind(".")] + '.don'
682 self.generator.writeCuve2DG(fileCuve2DG)
688 self.appliEficas.addJdcInSalome( self.fichier)
690 return (1, self.fichier)
694 #---------------------------------#
695 def saveFileAs(self, path = None):
696 #---------------------------------#
698 Public slot to save a file with a new name.
700 @param path directory to save the file in (string or QString)
701 @return tuple of two values (boolean, string) giving a success indicator and
702 the name of the saved file
704 return self.saveFile(path,1)
708 #---------------------------------------------#
709 def get_file(self,unite=None,fic_origine = ''):
710 #---------------------------------------------#
718 titre = "Choix unite %d " %unite
719 texte = "Le fichier %s contient une commande INCLUDE \n" % fic_origine
720 texte = texte+'Donnez le nom du fichier correspondant\n à l unité logique %d' % unite
721 labeltexte = 'Fichier pour unite %d :' % unite
723 titre = "Choix d'un fichier de poursuite"
724 texte = "Le fichier %s contient une commande %s\n" %(fic_origine,'POURSUITE')
725 texte = texte+'Donnez le nom du fichier dont vous \n voulez faire une poursuite'
727 QMessageBox.information( self, titre,QString.fromUtf8(texte))
728 fn = QFileDialog.getOpenFileName(self.appliEficas,
730 self.appliEficas.CONFIGURATION.savedir)
733 # ce retour est impose par le get_file d'I_JDC
736 ulfile = os.path.abspath(unicode(fn))
737 self.appliEficas.CONFIGURATION.savedir=os.path.split(ulfile)[0]
739 # On utilise le convertisseur défini par format_fichier
740 source=self.get_source(ulfile)
742 # On a réussi à convertir le fichier self.ulfile
745 # Une erreur a été rencontrée
747 return ulfile, jdcText
750 if __name__=='__main__':
751 import prefs # dans main
752 name='prefs_'+prefs.code
753 prefsCode=__import__(name)
755 if hasattr(prefsCode,'encoding'):
756 # Hack pour changer le codage par defaut des strings
759 sys.setdefaultencoding(prefs.encoding)
760 del sys.setdefaultencoding
763 # #CS_pbruno note: fait implicitement des trucs ces imports (grr)
768 # # Analyse des arguments de la ligne de commande
769 # options=session.parse(sys.argv)
772 app = QApplication(sys.argv)
773 mw = JDCEditor(None,'azAster.comm')
774 app.setMainWidget(mw)
775 app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
778 res = app.exec_loop()