1 #i -*- coding: iso-8859-1 -*-
10 import convert,generator
11 from Editeur import session
12 from Editeur import comploader
13 from Editeur import Objecttreeitem
21 VERSION_EFICAS = "EFICAS v1.17"
24 # -------------------------- #
26 class JDCEditor(QSplitter):
28 # -------------------------- #
33 def __init__(self,fn = None, jdc = None ,parent=None, editor = None, units = None, include=0):
34 #-------------------------------------------------------------------------------------------#
36 QSplitter.__init__(self, parent,'')
38 VERSION_CODE = session.d_env.cata
42 self.salome = self.parent.salome
43 self.appliEficas = self.parent.appliEficas
45 self.code = prefs.code
46 self.version_code = VERSION_CODE
47 self.titre=VERSION_EFICAS + ' pour '+ self.code
49 self.liste_simp_reel=[]
50 self.format_fichier='python' # par defaut
51 self.jdc_openturn_xml=""
52 self.jdc_openturn_std=""
56 self.CONFIGURATION = self.appliEficas.CONFIGURATION
57 self.CONFIGStyle = self.appliEficas.CONFIGStyle
60 if hasattr(qApp.mainWidget(),"statusBar"):
61 self.sb = qApp.mainWidget().statusBar()
63 self.vm = parent #viewManager
70 self.panel_courant=None
71 self.node_selected = None
73 self.isReadOnly = False
75 if not hasattr( readercata, 'reader' ) :
76 readercata.reader = readercata.READERCATA( self, self )
77 self.readercata = readercata.reader
79 #------- construction du jdc --------------
84 if self.fileName is not None: # fichier jdc fourni
85 self.fileInfo = QFileInfo(self.fileName)
86 self.fileInfo.setCaching(0)
88 self.jdc = self.readFile(self.fileName)
90 self.jdc.recorded_units=units
91 self.jdc.old_recorded_units=units
94 self.code = editor.code
95 self.version_code = editor.version_code
96 self.titre = editor.titre
97 self.dict_reels = editor.dict_reels
98 self.liste_simp_reel= editor.liste_simp_reel
99 self.format_fichier = editor.format_fichier
100 self.CONFIGURATION = editor.CONFIGURATION
101 self.CONFIGStyle = editor.CONFIGStyle
102 self.jdc = editor.jdc
104 self.lastModified = self.fileInfo.lastModified()
105 elif editor is not None:
106 self.jdc = editor.jdc
108 if not self.jdc: # nouveau jdc
110 self.jdc = self._newJDC(units=units)
112 self.jdc = self._newJDCInclude(units=units)
116 self.jdc.appli = self
120 txt_exception = self.jdc.cr.get_mess_exception()
123 qApp.restoreOverrideCursor()
124 self.affiche_infos("Erreur fatale au chargement de %s" %fn)
125 QMessageBox.critical( self, "Erreur fatale au chargement d'un fichier", txt_exception)
127 comploader.charger_composants("QT")
128 jdc_item=Objecttreeitem.make_objecttreeitem( self, "nom", self.jdc )
130 if (not self.jdc.isvalid()) and (not nouveau) :
131 self.viewJdcRapport()
133 #------- config widget --------------
136 self.tree = browser.JDCTree( jdc_item, self )
137 self.connect(self.tree,SIGNAL('selectionChanged(QListViewItem *)'),self.updatePanel)
142 if sh.height() < 300:
146 # Make sure tabbing through a QWorkspace works.
147 self.setFocusPolicy(QWidget.StrongFocus)
148 self._updateReadOnly(1)
150 # Set the editors size if it is too big for the parent.
151 if parent is not None:
153 bnd = req.boundedTo(parent.size())
155 if bnd.width() < req.width() or bnd.height() < req.height():
158 self.panel = QWidget(self)
159 #self.connect(self, SIGNAL('modificationChanged(bool)'), self.handleModificationChanged)
162 #-------------------------------------------------------------------#
163 def _updateReadOnly(self, bForce=1):
164 #-------------------------------------------------------------------#
166 Private method to update the readOnly information for this editor.
168 If bForce is True, then updates everything regardless if
169 the attributes have actually changed, such as during
170 initialization time. A signal is emitted after the
173 @param bForce 1 to force change, 0 to only update and emit
174 signal if there was an attribute change.
177 if self.fileName is None:
179 readOnly = not QFileInfo(self.fileName).isWritable() and 1 or 0
180 if not bForce and (readOnly == self.isReadOnly):
184 cap = "%s (ro)" % unicode(cap)
185 self.isReadOnly = readOnly
187 self.emit(PYSIGNAL('captionChanged'), (cap, self))
189 #--------------------------------#
190 def _newJDC( self ,units = None):
191 #--------------------------------#
193 Initialise un nouveau JDC vierge
195 CONTEXT.unset_current_step()
196 jdc=self.readercata.cata[0].JdC( procedure="",
198 cata=self.readercata.cata,
199 cata_ord_dico=self.readercata.cata_ordonne_dico,
200 rep_mat=self.CONFIGURATION.rep_mat
202 if units is not None:
203 jdc.recorded_units=units
204 jdc.old_recorded_units=units
208 #--------------------------------#
209 def _newJDCInclude( self ,units = None):
210 #--------------------------------#
212 Initialise un nouveau JDC vierge
214 import Extensions.jdc_include
215 JdC_aux=Extensions.jdc_include.JdC_include
216 CONTEXT.unset_current_step()
218 jaux=self.readercata.cata[0].JdC( procedure="",
220 cata=self.readercata.cata,
221 cata_ord_dico=self.readercata.cata_ordonne_dico,
222 rep_mat=self.CONFIGURATION.rep_mat,
226 J=JdC_aux( procedure="",
228 cata=self.readercata.cata,
229 cata_ord_dico=self.readercata.cata_ordonne_dico,
231 rep_mat=self.CONFIGURATION.rep_mat,
234 if units is not None:
235 J.recorded_units=units
236 J.old_recorded_units=units
240 #-----------------------#
241 def get_source(self,file):
242 #-----------------------#
244 format=self.format_fichier
246 # Il faut convertir le contenu du fichier en fonction du format
247 if convert.plugins.has_key(format):
248 # Le convertisseur existe on l'utilise
249 p=convert.plugins[format]()
251 text=p.convert('execnoparseur')
252 if not p.cr.estvide():
253 self.affiche_infos("Erreur a la conversion")
256 # Il n'existe pas c'est une erreur
257 self.affiche_infos("Type de fichier non reconnu")
258 QMessageBox.critical( self, "Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")
261 #---------------------------------------------#
262 def get_file(self,unite=None,fic_origine = ''):
263 #---------------------------------------------#
270 titre = "Choix unite %d " %unite
271 texte = "Le fichier %s contient une commande INCLUDE \n" % fic_origine
272 texte = texte+'Donnez le nom du fichier correspondant à l unité logique %d' % unite
273 labeltexte = 'Fichier pour unite %d :' % unite
275 titre = "Choix d'un fichier de poursuite"
276 texte = "Le fichier %s contient une commande %s\n" %(fic_origine,'POURSUITE')
277 texte = texte+'Donnez le nom du fichier dont vous voulez faire une poursuite'
279 QMessageBox.information( self, titre,texte)
280 fn = QFileDialog.getOpenFileName( self.CONFIGURATION.savedir,"", self, titre, "" )
285 ulfile = os.path.abspath(unicode(fn))
286 # On utilise le convertisseur défini par format_fichier
287 source=self.get_source(ulfile)
289 # On a réussi à convertir le fichier self.ulfile
292 # Une erreur a été rencontrée
294 return ulfile, jdcText
297 #-----------------------#
298 def readFile(self, fn):
299 #-----------------------#
301 Public slot to read the text from a file.
303 @param fn filename to read from (string or QString)
307 qApp.setOverrideCursor(Qt.waitCursor)
309 # ------------------------------------------------------------------------------------
311 # ------------------------------------------------------------------------------------
313 jdcName=os.path.basename(fn)
314 # Il faut convertir le contenu du fichier en fonction du format
315 if convert.plugins.has_key( self.format_fichier ):
316 # Le convertisseur existe on l'utilise
317 appli = self # CS_pbruno compatiblity parseur_python: self.appli.liste_simp_reel, self.appli.dict_reels
318 p=convert.plugins[self.format_fichier]()
320 text=p.convert('exec',appli)
321 if not p.cr.estvide():
322 self.affiche_infos("Erreur à la conversion")
324 CONTEXT.unset_current_step()
325 ## os.chdir(self.initialdir)
326 jdc=self.readercata.cata[0].JdC(procedure=text,
328 cata=self.readercata.cata,
329 cata_ord_dico=self.readercata.cata_ordonne_dico,
331 rep_mat=self.CONFIGURATION.rep_mat
333 # ----------------------------------------------------
335 # ----------------------------------------------------
336 self.modified = False
338 qApp.restoreOverrideCursor()
339 if self.fileInfo!= None :
340 self.lastModified = self.fileInfo.lastModified()
342 self.lastModified = 1
345 #----------------------------------------------#
346 def _viewText(self, txt, caption = "FILE_VIEWER"):
347 #----------------------------------------------#
348 w = qtCommun.ViewText( self.parent )
349 w.setCaption( caption )
353 #-----------------------#
354 def viewJdcSource(self):
355 #-----------------------#
356 format = self.format_fichier
357 f=open(self.fileName,'r')
360 self._viewText(texteSource, "JDC_SOURCE")
362 #-----------------------#
364 #-----------------------#
365 format = self.format_fichier
366 strSource = str( self.get_text_JDC(format) )
367 self._viewText(strSource, "JDC_RESULTAT")
369 #-----------------------#
370 def viewJdcRapport(self):
371 #-----------------------#
372 strRapport = str( self.jdc.report() )
373 self._viewText(strRapport, "JDC_RAPPORT")
375 #-----------------------#
376 def handleRenamed(self, fn):
377 #-----------------------#
379 Public slot to handle the editorRenamed signal.
381 @param fn filename to be set for the editor (QString or string).
383 self.fileName = unicode(fn)
384 self.setCaption(self.fileName)
386 if self.fileInfo is None:
387 self.fileInfo = QFileInfo(self.fileName)
388 self.fileInfo.setCaching(0)
390 self.lastModified = self.fileInfo.lastModified()
391 self.vm.setEditorName(self, self.fileName)
392 self._updateReadOnly(1)
394 #-----------------------#
395 def handleNewView(self):
396 #-----------------------#
398 Private slot to create a new view to an open document.
400 self.vm.newEditorView(self.fileName, self)#, self.isPythonFile)
402 #------------------------------------#
403 def handleModificationChanged(self, m):
404 #------------------------------------#
406 Private slot to handle the modificationChanged signal.
408 It emits the signal modificationStatusChanged with parameters
411 @param m modification status
413 if not m and self.fileInfo is not None:
414 self.lastModified = self.fileInfo.lastModified()
415 self.emit(PYSIGNAL('modificationStatusChanged'), (m, self))
417 #------------------------#
418 def hasSyntaxErrors(self):
419 #------------------------#
420 return False #CS_pbruno todo
426 Public method called by the viewmanager to finally get rid of us.
434 #------------------------------#
435 def affiche_infos(self,message):
436 #------------------------------#
438 if not hasattr(self.appliEficas,'MessageLabel') :
439 self.appliEficas.leLayout=QDockWindow(self.appliEficas)
440 self.appliEficas.MessageLabel = QLabel(self.appliEficas.leLayout,"MessageLabel")
441 self.appliEficas.MessageLabel.setAlignment(Qt.AlignBottom)
442 self.appliEficas.leLayout.setWidget(self.appliEficas.MessageLabel)
443 self.appliEficas.moveDockWindow(self.appliEficas.leLayout,Qt.DockBottom)
444 self.appliEficas.MessageLabel.setText(message)
445 self.appliEficas.MessageLabel.show()
446 self.appliEficas.leLayout.show()
448 self.sb.message(message)#,2000)
450 #------------------------------#
451 def updatePanel(self, jdcNode):
452 #------------------------------#
454 Appele a chaque changement de noeud
456 self.node_selected = jdcNode
462 if jdcNode.item.isactif():
463 self.panel = jdcNode.getPanel()
464 #print self.panel.__class__
466 self.panel = panelsQT.PanelInactif(self.node_selected,self)
469 self.panel = panelsQT.NoPanel(self)
474 #-------------------#
475 def init_modif(self):
476 #-------------------#
478 Met l'attribut modified a 'o' : utilise par Eficas pour savoir
479 si un JDC doit etre sauvegarde avant destruction ou non
482 self.emit(PYSIGNAL('modificationStatusChanged'), (True, self))
484 #-------------------#
485 def stop_modif(self):
486 #-------------------#
488 Met l'attribut modified à 'n' : utilisé par Eficas pour savoir
489 si un JDC doit etre sauvegardé avant destruction ou non
491 self.modified = False
492 self.emit(PYSIGNAL('modificationStatusChanged'), (False, self))
495 #-------------------#
497 #-------------------#
499 Stocke dans Eficas.noeud_a_editer le noeud à couper
501 if not self.node_selected.item.iscopiable():
502 QMessageBox.information( self, "Copie impossible",
503 "Cette version d'EFICAS ne permet que la copie d'objets de type 'Commande' ou mot-clé facteur")
505 self.parent.edit="couper"
506 self.parent.noeud_a_editer = self.node_selected
508 #-------------------#
510 #-------------------#
512 Stocke dans Eficas.noeud_a_editer le noeud a copier
514 if not self.node_selected.item.iscopiable():
515 QMessageBox.information( self, "Copie impossible",
516 "La copie d'un tel objet n'est pas permise")
518 self.parent.edit="copier"
519 self.parent.noeud_a_editer = self.node_selected
521 #-------------------#
523 #-------------------#
525 Lance la copie de l'objet place dans self.parent.noeud_a_editer
526 Ne permet que la copie d'objets de type Commande ou MCF
529 child=self.parent.noeud_a_editer.doPaste(self.node_selected)
531 traceback.print_exc()
532 QMessageBox.information( self, "Copie impossible",
533 "L'action de coller apres un tel objet n'est pas permise")
537 if self.message != '':
538 QMessageBox.critical( self, "Copie refusee", self.message)
540 self.affiche_infos("Copie refusée")
543 # il faut declarer le JDCDisplay_courant modifie
545 # suppression eventuelle du noeud selectionne
546 # si possible on renomme l objet comme le noeud couper
548 if self.parent.edit == "couper":
549 #nom = self.parent.noeud_a_editer.item.object.sd.nom
550 item=self.parent.noeud_a_editer.item
551 self.parent.noeud_a_editer.delete()
552 child.item.update(item)
553 #test,mess = child.item.nomme_sd(nom)
556 # on rend la copie a nouveau possible en liberant le flag edit
557 self.parent.edit="copier"
559 #---------------------#
560 def getFileName(self):
561 #---------------------#
564 #---------------------------#
565 def writeFile(self, fn, txt = None):
566 #------------------------------#
568 Public slot to write the text to a file.
570 @param fn filename to write to (string or QString)
571 @return flag indicating success
577 txt = self.get_text_JDC(self.format_fichier)
579 if len(txt) >= len(eol):
580 if txt[-len(eol):] != eol:
591 QMessageBox.critical(self, self.trUtf8('Save File'),
592 self.trUtf8('The file <b>%1</b> could not be saved.<br>Reason: %2')
593 .arg(unicode(fn)).arg(str(why)))
596 #------------------------------------
597 def writeFilesOpenturns(self,fn) :
598 #------------------------------------
599 base=fn[:fn.rfind(".")]
600 fileXML=base + '.xml'
601 fileSTD=base + '_std.py'
602 self.writeFile(fileXML,self.jdc_openturn_xml)
603 self.writeFile(fileSTD,self.jdc_openturn_std)
606 #-----------------------------#
607 def get_text_JDC(self,format):
608 #-----------------------------#
609 if generator.plugins.has_key(format):
610 # Le generateur existe on l'utilise
611 g=generator.plugins[format]()
612 jdc_formate=g.gener(self.jdc,format='beautifie')
613 if format == "openturns" :
614 self.jdc_openturn_xml=g.getOpenturnsXML()
615 self.jdc_openturn_std=g.getOpenturnsSTD()
616 if not g.cr.estvide():
617 self.affiche_infos("Erreur à la generation")
618 QMessageBox.critical( self, "Erreur a la generation","EFICAS ne sait pas convertir ce JDC")
623 # Il n'existe pas c'est une erreur
624 self.affiche_infos("Format %s non reconnu" % format)
625 QMessageBox.critical( self, "Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
629 #-------------------------------------------#
630 def saveFile(self, saveas = 0, path = None):
631 #-------------------------------------------#
633 Public slot to save the text to a file.
635 @param saveas flag indicating a 'save as' action
636 @param path directory to save the file in (string or QString)
637 @return tuple of two values (boolean, string) giving a success indicator and
638 the name of the saved file
640 self.modified = True #CS_pbruno test
642 if not saveas and not self.modified:#self.isModified():
643 return (0, None) # do nothing if text wasn't changed
646 if saveas or self.fileName is None:
647 if path is None and self.fileName is not None:
648 path = os.path.dirname(unicode(self.fileName))
650 path=self.CONFIGURATION.savedir
651 fn = QFileDialog.getSaveFileName(path,
652 self.trUtf8("JDC (*.comm);;" "All Files (*)"),self, None,
653 self.trUtf8("Save File"), '', 0)
656 ext = QFileInfo(fn).extension()
660 if QFileInfo(fn).exists():
661 abort = QMessageBox.warning(
663 self.trUtf8("Sauvegarde Fichier"),
664 self.trUtf8("Le fichier <b>%1</b> existe deja.").arg(fn),
665 self.trUtf8("&Remplacer"),
666 self.trUtf8("&Abandonner") )
670 fn = unicode(QDir.convertSeparators(fn))
677 if self.writeFile(fn):
679 self.modified = False
680 self.setCaption(self.fileName)
681 if self.fileInfo is None or saveas:
682 self.fileInfo = QFileInfo(self.fileName)
683 self.fileInfo.setCaching(0)
684 self.emit(PYSIGNAL('editorRenamed'), (self.fileName,))
685 self.lastModified = self.fileInfo.lastModified()
686 if newName is not None:
687 self.vm.addToRecentList(newName)
688 self.emit(PYSIGNAL('editorSaved'), (self.fileName,))
690 if self.code == "OPENTURNS" :
691 self.writeFilesOpenturns(fn)
693 self.parent.appli.addJdcInSalome( self.fileName)
694 if self.code == 'ASTER':
695 self.parent.appli.createOrUpdateMesh(self)
699 return (1, self.fileName)
703 #---------------------------------#
704 def saveFileAs(self, path = None):
705 #---------------------------------#
707 Public slot to save a file with a new name.
709 @param path directory to save the file in (string or QString)
710 @return tuple of two values (boolean, string) giving a success indicator and
711 the name of the saved file
713 return self.saveFile(1, path)
716 if __name__=='__main__':
717 if hasattr(prefs,'encoding'):
718 # Hack pour changer le codage par defaut des strings
721 sys.setdefaultencoding(prefs.encoding)
722 del sys.setdefaultencoding
725 #CS_pbruno note: fait implicitement des trucs ces imports (grr)
730 # Analyse des arguments de la ligne de commande
731 options=session.parse(sys.argv)
734 app = QApplication(sys.argv)
735 mw = JDCEditor('azAster.comm')
736 app.setMainWidget(mw)
737 app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
740 res = app.exec_loop()