1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 import types,sys,os, re
24 from determine import monEnvQT5
26 from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog, QApplication, QSplitter
27 from PyQt5.QtGui import QPalette
28 from PyQt5.QtCore import QProcess, QFileInfo, QTimer, Qt, QDir, QSize
30 from PyQt4.QtGui import *
31 from PyQt4.QtCore import *
34 from datetime import date
35 from Extensions.i18n import tr
40 import convert, generator
41 from Editeur import session
42 from Editeur import comploader
43 from Editeur import Objecttreeitem
44 from desBaseWidget import Ui_baseWidget
45 from monViewTexte import ViewText
46 from monWidgetCreeParam import MonWidgetCreeParam
50 DictExtensions= {"MAP" : ".map"}
55 class JDCEditor(Ui_baseWidget,QWidget):
56 # ----------------------------------------- #
61 def __init__ (self,appli,fichier = None, jdc = None, QWParent=None, units = None, include=0 , vm=None):
62 #----------------------------------------------------------------------------------------------------------#
64 QWidget.__init__(self,None)
68 self.widgetOptionnel=None
69 self.fenetreCentraleAffichee=None
70 self.dejaDansPlieTout=False
71 self.afficheCommandesPliees = True
72 self.listeDesListesOuvertes=set()
73 self.appliEficas = appli
74 self.appli = appli #---- attendu par IHM
76 self.fichier = fichier
79 self.QWParent = QWParent
80 self.couleur = Qt.black
83 self.salome = self.appliEficas.salome
86 print "dans JDC pas d appli ????????"
88 # ces attributs sont mis a jour par definitCode appelee par newEditor
89 self.code = self.appliEficas.CONFIGURATION.code
90 # tres vite a cause du tag. doit etre pase dans CONFIGURATION
92 self.afficheListesPliees=False
93 if self.code == "ASTER" or self.code == "monCode" : self.afficheListesPliees =True
95 self.mode_nouv_commande=self.appliEficas.CONFIGURATION.mode_nouv_commande
96 self.affiche=self.appliEficas.CONFIGURATION.affiche
97 #if self.code in ['MAP','CARMELCND','PSEN'] : self.afficheCommandesPliees=False
98 if self.code in ['MAP','CARMELCND'] : self.afficheCommandesPliees=False
99 if self.code in ['MAP',] :
100 self.widgetTree.close()
102 self.appliEficas.resize(1440,self.appliEficas.height())
104 self.appliEficas.resize(1800,self.appliEficas.height())
106 self.version_code = session.d_env.cata
108 if not hasattr ( self.appliEficas, 'readercata') or self.appliEficas.multi==True:
109 self.readercata = readercata.READERCATA( self, self.appliEficas )
110 self.appliEficas.readercata=self.readercata
112 self.readercata=self.appliEficas.readercata
113 if self.readercata.fic_cata == None : return #Sortie Salome
114 self.titre=self.readercata.titre
115 self.Ordre_Des_Commandes=self.readercata.Ordre_Des_Commandes
116 self.Classement_Commandes_Ds_Arbre=self.readercata.Classement_Commandes_Ds_Arbre
118 self.format = self.appliEficas.format_fichier
121 self.splitterSizes = [320,1320,320]
122 self.oldSizeWidgetOptionnel = 320
123 self.liste_simp_reel=[]
126 nameConf='configuration_'+self.code
127 configuration=__import__(nameConf)
128 self.CONFIGURATION = self.appliEficas.CONFIGURATION
129 self.CONFIGStyle = self.appliEficas.CONFIGStyle
132 self.CONFIGURATION.generator_module
133 _module = __import__(self.CONFIGURATION.generator_module)
134 info = _module.entryPoint()
135 generator.plugins.addEntryPoint(info)
140 self.CONFIGURATION.convert_module
141 print self.CONFIGURATION.convert_module
142 _module = __import__(self.CONFIGURATION.convert_module)
143 info = _module.entryPoint()
144 convert.plugins.addEntryPoint(info)
149 if hasattr(self.appliEficas,"statusBar"):
150 self.sb = self.appliEficas.statusBar()
153 self.lastModified = 0
155 self.modified = False
156 self.isReadOnly = False
157 self.node_selected = []
160 if self.code in ['Adao','MAP'] : self.afficheApresInsert=True
161 else : self.afficheApresInsert=False
162 if self.code in ['TELEMAC',] : self.enteteQTree='premier'
163 else : self.enteteQTree='complet'
164 if self.code in ['Adao','TELEMAC'] : self.affichePlie=True
165 else : self.affichePlie=False
167 self.Commandes_Ordre_Catalogue =self.readercata.Commandes_Ordre_Catalogue
169 #------- construction du jdc --------------
174 if self.fichier is not None: # fichier jdc fourni
175 self.fileInfo = QFileInfo(self.fichier)
176 self.fileInfo.setCaching(0)
180 self.jdc = self.readFile(self.fichier)
183 print "mauvaise lecture"
186 if self.jdc is not None and units is not None:
187 self.jdc.recorded_units=units
188 self.jdc.old_recorded_units=units
190 if not self.jdc: # nouveau jdc
192 self.jdc = self._newJDC(units=units)
194 self.jdc = self._newJDCInclude(units=units)
198 self.jdc.appli = self
199 self.jdc.lang = self.appli.langue
200 self.jdc.aReafficher=False
204 txt_exception = self.jdc.cr.get_mess_exception()
207 QApplication.restoreOverrideCursor()
208 self.affiche_infos(tr("Erreur fatale au chargement de %s",str(fichier)),Qt.red)
209 if (self.appliEficas.ssIhm == False) : QMessageBox.critical( self, tr("Erreur fatale au chargement d'un fichier"), txt_exception)
211 comploader.charger_composants("QT")
212 jdc_item=Objecttreeitem.make_objecttreeitem( self, "nom", self.jdc )
213 if (not self.jdc.isvalid()) and (not self.nouveau) and (self.appliEficas.ssIhm == False):
214 self.viewJdcRapport()
219 self.tree = browser.JDCTree( jdc_item, self )
220 self.appliEficas.construitMenu()
221 self.saveSplitterSizes()
227 #-------------------# Pour execution avec output et error dans le bash
229 #-------------------#
230 if self.modified or self.fichier==None : self.saveFile()
232 #lancement avec le .bat
233 path1 = os.path.abspath(os.path.join(os.path.abspath(__file__), '../','../','PSEN_Eficas','PSEN'))
234 WrapperFilePath = os.path.join(path1, 'PSSEWrapper.py')
236 p = subprocess.Popen(['python',WrapperFilePath])
237 (out,err)=p.communicate()
241 #--------------------------------#
242 def _newJDC( self ,units = None):
243 #--------------------------------#
245 Initialise un nouveau JDC vierge
248 CONTEXT.unset_current_step()
251 if self.code == "CARMELCND" : texte=self._newJDCCND()
252 if self.code == "ZCRACKS" : texte=self._newZCRACKS()
253 if self.code == "TELEMAC" : texte=self._newTELEMAC()
254 if self.code == "PSEN" : texte = self._newPSEN()
255 # texte=self.newTexteCND
257 jdc=self.readercata.cata[0].JdC( procedure =texte,
259 cata=self.readercata.cata,
260 cata_ord_dico=self.readercata.cata_ordonne_dico,
261 rep_mat=self.CONFIGURATION.rep_mat
263 jdc.lang = self.appli.langue
264 if units is not None:
265 jdc.recorded_units=units
266 jdc.old_recorded_units=units
267 ## PNPN est ce que la ligne suivante est bien utile ?
268 if texte == "" :jdc.analyse()
271 #--------------------------------#
272 def _newJDCInclude( self ,units = None):
273 #--------------------------------#
275 Initialise un nouveau JDC vierge
277 import Extensions.jdc_include
278 JdC_aux=Extensions.jdc_include.JdC_include
279 CONTEXT.unset_current_step()
281 jaux=self.readercata.cata[0].JdC( procedure="",
283 cata=self.readercata.cata,
284 cata_ord_dico=self.readercata.cata_ordonne_dico,
285 rep_mat=self.CONFIGURATION.rep_mat,
289 J=JdC_aux( procedure="",
291 cata=self.readercata.cata,
292 cata_ord_dico=self.readercata.cata_ordonne_dico,
294 rep_mat=self.CONFIGURATION.rep_mat,
297 if units is not None:
298 J.recorded_units=units
299 J.old_recorded_units=units
303 #-------------------------------#
304 def readFile(self, fn):
305 #--------------------------------#
307 Public slot to read the text from a file.
308 @param fn filename to read from (string or QString)
312 # ------------------------------------------------------------------------------------
314 # ------------------------------------------------------------------------------------
316 jdcName=os.path.basename(fn)
317 # Il faut convertir le contenu du fichier en fonction du format
318 if convert.plugins.has_key( self.appliEficas.format_fichier_in ):
319 # Le convertisseur existe on l'utilise
321 p=convert.plugins[self.appliEficas.format_fichier_in]()
323 if p.text=="" : self.nouveau=1
324 pareil,texteNew=self.verifieCHECKSUM(p.text)
326 if pareil == False and (self.appliEficas.ssIhm == False) :
327 QMessageBox.warning( self, tr("fichier modifie"),tr("Attention! fichier change hors EFICAS"))
329 memeVersion,texteNew=self.verifieVersionCataDuJDC(p.text)
330 if memeVersion == 0 : texteNew=self.traduitCatalogue(texteNew)
332 text=p.convert('exec',self.appliEficas)
333 if not p.cr.estvide():
334 self.affiche_infos("Erreur a la conversion",Qt.red)
336 self.affiche_infos("Type de fichier non reconnu",Qt.red)
337 if self.appliEficas.ssIhm == False:
338 QMessageBox.critical( self, tr("Type de fichier non reconnu"),
339 tr("EFICAS ne sait pas ouvrir le type de fichier %s" ,self.appliEficas.format_fichier_in))
342 CONTEXT.unset_current_step()
343 jdc=self.readercata.cata[0].JdC(procedure=text,
345 cata=self.readercata.cata,
346 cata_ord_dico=self.readercata.cata_ordonne_dico,
348 rep_mat=self.CONFIGURATION.rep_mat
350 # ----------------------------------------------------
352 # ----------------------------------------------------
353 self.modified = False
355 # qApp.restoreOverrideCursor()
356 if self.fileInfo!= None :
357 self.lastModified = self.fileInfo.lastModified()
359 self.lastModified = 1
360 nouveauTitre=self.titre+" "+str(os.path.basename(self.fichier))
361 self.appliEficas.setWindowTitle(nouveauTitre)
365 #-----------------------#
366 def get_source(self,file):
367 #-----------------------#
369 # Il faut convertir le contenu du fichier en fonction du format
370 if convert.plugins.has_key(self.format):
371 # Le convertisseur existe on l'utilise
372 p=convert.plugins[self.format]()
374 text=p.convert('execnoparseur')
375 if not p.cr.estvide():
376 self.affiche_infos("Erreur a la conversion",Qt.red)
379 # Il n'existe pas c'est une erreur
380 self.affiche_infos("Type de fichier non reconnu",Qt.red)
381 QMessageBox.critical( self, tr("Type de fichier non reconnu"),tr("EFICAS ne sait pas ouvrir ce type de fichier"))
384 #-----------------------------------------------------------------------#
385 def _viewText(self, txt, caption = "FILE_VIEWER",largeur=1200,hauteur=600):
386 #--------------------------------------------------------------------#
387 w = ViewText( self.QWParent,self ,caption,txt,largeur,hauteur)
391 #----------------------------------------------#
392 def __generateTempFilename(self, prefix, suffix):
393 #----------------------------------------------#
395 (fd, filename) = tempfile.mkstemp(prefix=prefix, suffix=suffix)
401 #----------------------------------------------#
402 def _viewTextExecute(self, txt, prefix, suffix):
403 #----------------------------------------------#
404 self.w = ViewText( self.QWParent )
405 self.w.setWindowTitle( "execution" )
406 self.monExe=QProcess(self.w)
407 pid=self.monExe.pid()
408 nomFichier = self.__generateTempFilename(prefix, suffix = ".sh")
409 f=open(nomFichier,'w')
413 self.monExe.readyReadStandardOutput.connect( self.readFromStdOut)
414 self.monExe.readyReadStandardError.connect( self.readFromStdErr)
416 self.connect(self.monExe, SIGNAL("readyReadStandardOutput()"), self.readFromStdOutQT4 )
417 self.connect(self.monExe, SIGNAL("readyReadStandardError()"), self.readFromStdErrQT4 )
418 exe='sh ' + nomFichier
419 self.monExe.start(exe)
420 self.monExe.closeWriteChannel()
423 commande="rm "+ nomFichier
428 def readFromStdErr(self):
429 a=self.monExe.readAllStandardError()
430 self.w.view.append(str(a.data(),len(a)))
432 def readFromStdErr(self) :
433 a=self.monExe.readAllStandardOutput()
434 self.w.view.append(str(a.data(),len(a)))
436 def readFromStdErrQT4(self):
437 a=self.monExe.readAllStandardError()
438 self.w.view.append(QString.fromUtf8(a.data(),len(a))) ;
440 def readFromStdOutQT4(self) :
441 a=self.monExe.readAllStandardOutput()
442 self.w.view.append(QString.fromUtf8(a.data(),len(a))) ;
446 #-----------------------#
447 def gestionParam(self):
448 #-----------------------#
449 w = MonWidgetCreeParam( self)
452 #-----------------------#
453 def viewJdcSource(self):
454 #-----------------------#
455 f=open(self.fichier,'r')
458 self._viewText(texteSource, "JDC_SOURCE")
460 #-----------------------#
462 #-----------------------#
463 strSource = str( self.get_text_JDC(self.format) )
464 self._viewText(strSource, "JDC_RESULTAT")
466 #-----------------------#
467 def viewJdcRapport(self):
468 #-----------------------#
469 strRapport = unicode( self.jdc.report() )
470 # on ajoute les regles
472 self._viewText(strRapport, "JDC_RAPPORT")
474 #-----------------------#
475 def viewJdcRegles(self):
476 #-----------------------#
477 if self.tree :self.tree.AppelleBuildLBRegles()
484 Public method called by the viewmanager to finally get rid of us.
490 #----------------------------------------------#
491 def affiche_infos(self,message,couleur=Qt.black):
492 #----------------------------------------------#
494 mapalette=self.sb.palette()
495 mapalette.setColor( QPalette.WindowText, couleur )
496 self.sb.setPalette( mapalette );
497 self.sb.showMessage(message,4000)
500 #------------------------------#
501 def affiche_alerte(self,titre,message):
502 #------------------------------#
503 # appele par I_MACRO_ETAPE
504 QMessageBox.information( self, titre, message)
506 #-----------------------------------#
507 def affiche_commentaire(self,message):
508 #-----------------------------------#
509 self.labelCommentaire.setText(message)
510 QTimer.singleShot(6000, self.rendInvisible)
512 #----------------------#
513 def rendInvisible(self):
514 #----------------------#
515 self.labelCommentaire.setText("")
517 #-------------------#
518 def init_modif(self):
519 #-------------------#
521 Met l'attribut modified a 'o' : utilise par Eficas pour savoir
522 si un JDC doit etre sauvegarde avant destruction ou non
526 #---------------------------------------#
527 def chercheNoeudSelectionne(self,copie=1):
528 #---------------------------------------#
530 appele par Cut et Copy pour positionner self.node_selected
532 self.node_selected=[]
533 if len(self.tree.selectedItems()) == 0 : return
534 self.node_selected=self.tree.selectedItems()
537 #---------------------#
538 def handleSupprimer(self):
539 #---------------------#
540 self.chercheNoeudSelectionne()
541 if len(self.node_selected) == 0 : return
542 self.QWParent.noeud_a_editer = []
543 if self.node_selected[0]==self.tree.racine: return
544 if len(self.node_selected) == 1 : self.node_selected[0].delete()
545 else : self.node_selected[0].deleteMultiple(self.node_selected)
547 #---------------------#
548 def handleRechercher(self):
549 #---------------------#
550 from monRecherche import DRecherche
551 monRechercheDialg=DRecherche(parent=self,fl=0)
552 monRechercheDialg.show()
554 #---------------------#
555 def handleDeplier(self):
556 #---------------------#
557 if self.tree == None : return
558 #self.tree.collapseAll()
561 self.tree.expandItem(self.tree.topLevelItem(0))
563 if self.fenetreCentraleAffichee != None :
564 if hasattr(self.fenetreCentraleAffichee.node,'plieToutEtReaffiche'):
565 self.fenetreCentraleAffichee.node.plieToutEtReaffiche()
568 self.tree.expandItem(self.tree.topLevelItem(0))
570 if self.fenetreCentraleAffichee != None :
571 if hasattr(self.fenetreCentraleAffichee.node,'deplieToutEtReaffiche'):
572 self.fenetreCentraleAffichee.node.deplieToutEtReaffiche()
574 #---------------------#
575 def handleEditCut(self):
576 #---------------------#
578 Stocke dans Eficas.noeud_a_editer le noeud a couper
580 #print "handleEditCut"
581 self.chercheNoeudSelectionne()
582 self.QWParent.edit="couper"
583 self.QWParent.noeud_a_editer = self.node_selected
585 #-----------------------#
586 def handleEditCopy(self):
587 #-----------------------#
589 Stocke dans Eficas.noeud_a_editer le noeud a copier
591 self.chercheNoeudSelectionne()
592 if len(self.node_selected) == 0 : return
593 if len(self.node_selected) == 1 : self.node_selected[0].update_node_label_in_blue()
594 else : self.node_selected[0].update_plusieurs_node_label_in_blue(self.node_selected)
595 self.QWParent.edit="copier"
596 self.QWParent.noeud_a_editer = self.node_selected
598 #------------------------#
599 def handleEditPaste(self):
600 #------------------------#
602 Lance la copie de l'objet place dans self.QWParent.noeud_a_editer
603 Ne permet que la copie d'objets de type Commande ou MCF
605 self.chercheNoeudSelectionne()
606 if (not(hasattr(self.QWParent,'noeud_a_editer'))) or len(self.QWParent.noeud_a_editer)==0:
607 QMessageBox.information( self,
608 tr("Copie impossible"),
609 tr("Veuillez selectionner un objet a copier"))
611 if len(self.node_selected) != 1 :
612 QMessageBox.information( self,
613 tr("Copie impossible"),
614 tr("Veuillez selectionner un seul objet : la copie se fera apres le noeud selectionne"))
617 if len(self.QWParent.noeud_a_editer)!=1:
618 self.handleEditPasteMultiple()
621 noeudOuColler=self.node_selected[0]
623 if noeudOuColler == self.tree.racine:
627 #indexNoeudOuColler=noeudOuColler.treeParent.children.index(noeudOuColler)
628 indexNoeudOuColler=self.getTreeIndex(noeudOuColler)
631 noeudACopier=self.QWParent.noeud_a_editer[0]
632 #indexNoeudACopier=noeudACopier.treeParent.children.index(noeudACopier)
633 indexNoeudACopier=self.getTreeIndex(noeudACopier)
635 QMessageBox.information( self, tr("Copie impossible"), tr("Aucun Objet n a ete copie ou coupe"))
638 if (self.QWParent.edit != "couper"):
640 if noeudOuColler == self.tree.racine :
641 child=noeudOuColler.doPastePremier(noeudACopier)
643 child=noeudACopier.doPaste(noeudOuColler,pos)
644 if child==None or child==0:
645 QMessageBox.critical( self,tr( "Copie refusee"),tr('Eficas n a pas reussi a copier l objet'))
647 self.affiche_infos("Copie refusee",Qt.red)
648 if noeudACopier.treeParent.editor != noeudOuColler.treeParent.editor:
650 nom=noeudACopier.item.sd.nom
651 child.item.nomme_sd(nom)
658 traceback.print_exc()
659 QMessageBox.critical( self,tr( "Copie refusee"),tr('Copie refusee pour ce type d objet'))
661 self.affiche_infos("Copie refusee",Qt.red)
664 # il faut declarer le JDCDisplay_courant modifie
665 # suppression eventuelle du noeud selectionne
666 # si possible on renomme l objet comme le noeud couper
668 if (self.QWParent.edit == "couper"):
670 if noeudACopier.treeParent.editor != noeudOuColler.treeParent.editor:
671 QMessageBox.critical( self, tr("Deplacement refuse"),tr('Deplacement refuse entre 2 fichiers. Seule la copie est autorisee '))
675 # indexNoeudACopier=noeudACopier.treeParent.children.index(noeudACopier)
676 indexNoeudACopier=self.getTreeIndex(noeudACopier)
677 noeudACopier.treeParent.item.deplaceEntite(indexNoeudACopier,indexNoeudOuColler,pos)
678 noeudACopier.treeParent.build_children()
683 self.QWParent.noeud_a_editer=[]
685 # on rend la copie a nouveau possible en liberant le flag edit
686 self.QWParent.edit="copier"
687 noeudACopier.select()
689 #----------------------------------#
690 def handleDeplaceMultiple(self):
691 #----------------------------------#
694 #----------------------------------#
695 def handleEditPasteMultiple(self):
696 #----------------------------------#
698 # On ne garde que les niveaux "Etape"
699 # On insere dans l'ordre du JDC
700 listeNoeudsACouper=[]
704 from InterfaceQT4 import compojdc
705 noeudOuColler=self.node_selected[0]
706 if not (isinstance(noeudOuColler.treeParent, compojdc.Node)):
707 QMessageBox.information( self,
708 tr("Copie impossible a cet endroit",),
709 tr("Veuillez selectionner une commande, un parametre, un commentaire ou une macro"))
711 indexNoeudOuColler=noeudOuColler.treeParent.children.index(noeudOuColler)
713 for noeud in self.QWParent.noeud_a_editer :
714 if not (isinstance(noeud.treeParent, compojdc.Node)): continue
715 indexInTree=noeud.treeParent.children.index(noeud)
717 for index in listeIndex:
718 if index < indexInTree : indice = indice +1
719 listeIndex.insert(indice, indexInTree)
720 listeNoeudsACouper.insert(indice, noeud)
722 noeudJdc=noeudOuColler.treeParent
724 # on les cree a l'envers parcequ'on ajoute a NoeudOuColler
726 for index in listeIndex:
728 if indexNoeudOuColler < index:
729 indexTravail=indexTravail+dejaCrees
730 noeudOuColler=noeudJdc.children[indexNoeudOuColler]
731 noeud=noeudJdc.children[indexTravail]
732 child=noeud.doPaste(noeudOuColler)
733 listeChild.append(child)
734 dejaCrees=dejaCrees+1
736 self.QWParent.noeud_a_editer = []
737 for i in range(len(listeIndex)):
738 noeud=noeudJdc.children[indexNoeudOuColler+1+i]
739 self.QWParent.noeud_a_editer.append(noeud)
742 if self.QWParent.edit !="couper" : return
744 for index in listeIndex:
746 if indexNoeudOuColler < index:
747 indexTravail=indexTravail+(len(listeIndex))
748 noeud=noeudJdc.children[indexTravail]
750 listeItem.append(noeud.item)
751 listeASupprimer.append(noeud)
753 for i in range(len(listeChild)):
754 self.tree.item.suppitem(listeItem[i])
755 listeChild[i].item.update(listeItem[i])
757 self.QWParent.noeud_a_editer = []
760 #---------------------#
761 def getFileName(self):
762 #---------------------#
765 #---------------------------#
766 def get_file_variable(self) :
767 #---------------------------#
768 titre = tr("Choix d'un fichier XML")
769 texte = tr("Le fichier contient une commande MODEL\n")
770 texte = texte+tr('Donnez le nom du fichier XML qui contient la description des variables')
771 QMessageBox.information( self, titre,tr(texte))
773 fichier = QFileDialog.getOpenFileName(self.appliEficas,
774 tr('Ouvrir Fichier'),
775 self.appliEficas.CONFIGURATION.savedir,
776 tr('Wrapper Files (*.xml);;''All Files (*)'))
779 #--------------------------------------------------#
780 def writeFile(self, fn, txt = None,formatLigne="beautifie"):
781 #--------------------------------------------------#
783 Public slot to write the text to a file.
785 @param fn filename to write to string
786 @return flag indicating success
792 txt = self.get_text_JDC(self.format,formatLigne=formatLigne)
794 if len(txt) >= len(eol):
795 if txt[-len(eol):] != eol:
799 txt=self.ajoutVersionCataDsJDC(txt)
800 checksum=self.get_checksum(txt)
808 QMessageBox.critical(self, tr('Sauvegarde du Fichier'),
809 tr('Le fichier')+str(fn) + tr('n a pas pu etre sauvegarde : ') + str(why))
812 #-----------------------------------------------------------#
813 def get_text_JDC(self,format,pourRun=0,formatLigne="beautifie"):
814 #-----------------------------------------------------------#
815 if self.code == "MAP" and not(generator.plugins.has_key(format)): format = "MAP"
816 if generator.plugins.has_key(format):
818 # Le generateur existe on l'utilise
819 self.generator=generator.plugins[format]()
821 jdc_formate=self.generator.gener(self.jdc,format=formatLigne,config=self.appliEficas.CONFIGURATION)
822 if pourRun : jdc_formate=self.generator.textePourRun
824 QMessageBox.critical(self, tr("Erreur a la generation"),str(e))
825 if not self.generator.cr.estvide():
826 self.affiche_infos(tr("Erreur a la generation"),Qt.red)
827 QMessageBox.critical( self, tr("Erreur a la generation"),tr("EFICAS ne sait pas convertir ce JDC"))
832 # Il n'existe pas c'est une erreur
833 self.affiche_infos(tr("Format %s non reconnu" , self.format),Qt.red)
834 QMessageBox.critical( self, "Format non reconnu" ,tr("EFICAS ne sait pas convertir le JDC selon le format "+ self.format))
840 fonction="run"+self.code
841 if fonction in JDCEditor.__dict__.keys(): apply(JDCEditor.__dict__[fonction],(self,))
846 fonction="saveRun"+self.code
847 if fonction in JDCEditor.__dict__.keys(): apply(JDCEditor.__dict__[fonction],(self,))
853 if not(self.jdc.isvalid()):
854 QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution MAP"))
856 if len(self.jdc.etapes) != 1 :
857 QMessageBox.critical( self, tr("Execution impossible "),tr("le JDC doit contenir un et un seul composant"))
859 if self.modified or self.fichier==None :
860 self.fichierMapInput = self.__generateTempFilename(prefix = "map_run", suffix = ".map")
861 texte=self.get_text_JDC("MAP")
862 self.writeFile( self.fichierMapInput, txt = texte)
864 self.fichierMapInput=self.fichier
865 composant=self.jdc.etapes[0].nom.lower()[0:-5]
868 # :TRICKY: to determine if a component requires SALOME, loads the component from Eficas catalog
869 # then instantiate corresponding class and call getUseSalome() method
871 from mapengine.spec import factory
872 mapComponent = factory.new(composant)[0]
875 if mapComponent.getUseSalome():
876 command += " -r sappli"
877 textePython=(command + " run -n "+composant +" -i "+self.fichierMapInput)
880 self._viewTextExecute( textePython,"map_run",".sh")
882 # commande="rm "+self.fichierMapInput
883 # os.system(commande)
887 print traceback.print_exc()
889 #-------------------#
890 def runZCRACKS(self):
891 #-------------------#
892 if not(self.jdc.isvalid()):
893 QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution "))
895 if self.modified or self.fichier==None :
897 self.fichierZcracksInput = self.__generateTempFilename(prefix = "zcracks_run", suffix = ".z7p")
898 texte=self.get_text_JDC("ZCRACKS",pourRun=1)
899 self.writeFile( self.fichierZcracksInput, txt = texte)
901 self.fichierZcracksInput=self.fichier
903 #commande ="Zrun -zp "
905 textePython=(commande + self.fichierZcracksInput)
906 self._viewTextExecute( textePython,"run_zcracks",".sh")
908 print traceback.print_exc()
910 #-------------------#
911 def runCARMELCND(self):
912 #-------------------#
913 #if not(self.jdc.isvalid()):
914 # QMessageBox.critical( self, tr( "Execution impossible "),tr("le JDC doit etre valide pour une execution "))
916 if self.modified or self.fichier==None :
917 QMessageBox.critical( self, tr( "Execution impossible "),tr("Sauvegarder SVP avant l'execution "))
919 if not hasattr(self,'generator'): texte=self.get_text_JDC(self.format)
920 from PrepareRunCarmel import prepareRunCarmel
921 fichierGenerique=os.path.basename(self.fichier).split(".")[0]
922 repMed=os.path.dirname(self.fichier)
923 repExeCarmel=self.generator.get_repExeCarmel()
924 textePython=prepareRunCarmel(repExeCarmel,repMed,fichierGenerique)
925 nomFichier = self.__generateTempFilename("carmel_run", suffix = ".sh")
926 f=open(nomFichier,'w')
929 commande="xterm -e sh "+nomFichier +"\n"
932 # self._viewTextExecute( textePython,"carmel_run",".sh")
933 #except Exception, e:
934 # print traceback.print_exc()
936 #-------------------#
937 def runCarmelCS(self):
938 #-------------------#
940 commande="runSession pilotyacsCS.py"
943 print traceback.print_exc()
945 #-----------------------------------------------------#
946 def determineNomFichier(self,path,extension):
947 #-----------------------------------------------------#
948 if DictExtensions.has_key(self.appli.code) :
949 chaine1="JDC (*"+DictExtensions[self.appli.code]+");;"
950 extensions= tr(chaine1+ "All Files (*)")
952 extensions= tr("JDC (*.comm);;" "All Files (*)")
954 if self.appli.code == "MAP" :
955 extensions = extensions + ";; Run (*.input);;"
957 fn = QFileDialog.getSaveFileName( self,
958 tr("sauvegarde"), path,
960 QFileDialog.DontConfirmOverwrite)
961 if fn == None : return (0, None)
962 if monEnvQT5 : fn=fn[0]
963 if fn=='': return (0, None)
965 ext = QFileInfo(fn).suffix()
966 if ext == '': fn+=extension
968 if QFileInfo(fn).exists():
970 msgBox = QMessageBox(self)
971 msgBox.setWindowTitle(tr("Sauvegarde du Fichier"))
972 msgBox.setText(tr("Le fichier <b>%s</b> existe deja.", unicode(fn)))
973 msgBox.addButton(tr("&Ecraser"),0)
974 msgBox.addButton(tr("&Abandonner"),1)
977 abort = QMessageBox.warning(self,
978 tr("Sauvegarde du Fichier"),
979 tr("Le fichier <b>%s</b> existe deja.",str(fn)),
982 if abort == 1 : return (0, "")
986 def saveRunMAP(self):
989 if not(self.jdc.isvalid()):
990 QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
991 tr("Un JdC valide est necessaire pour creer un .input")
995 composant=self.jdc.etapes[0].nom.lower()[0:-5]
997 QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
998 tr("Choix du composant obligatoire")
1001 if hasattr(self.CONFIGURATION, "savedir"): path=self.CONFIGURATION.savedir
1005 if self.fichier is not None and self.fichier != "" :
1006 maBase=str(QFileInfo(self.fichier).baseName())+".input"
1007 monPath=str(QFileInfo(self.fichier).absolutePath())
1008 monNomFichier=os.path.join(monPath,maBase)
1009 elif hasattr(self,'monNomFichierInput'):
1010 monNomFichier=self.monNomFichierInput
1013 monDialog=QFileDialog(self.appliEficas)
1014 monDialog.setDirectory (path)
1015 monDialog.setWindowTitle ("Save")
1017 for c in monDialog.children():
1018 if isinstance(c,QDialogButtonBox):
1019 for b in c.children():
1020 if isinstance(b,QPushButton):
1022 if (not monEnvQT5) and avant.toLatin1()=="&Open": b.setText("Save")
1023 if monEnvQT5 and avant=="&Open": b.setText("Save")
1025 mesFiltres= "input Map (*.input);;All Files (*)"
1027 mesFiltres=QStringList()
1028 mesFiltres << "input Map (*.input)" << "All Files (*)"
1029 monDialog.setNameFilters(mesFiltres)
1030 if monNomFichier!="" : monDialog.selectFile(monNomFichier)
1031 BOk=monDialog.exec_()
1033 if monEnvQT5 : fn=str(monDialog.selectedFiles()[0])
1034 else : fn=str(monDialog.selectedFiles()[0].toLatin1())
1035 if fn == "" or fn == None : return
1036 if not fn.endswith(".input"):
1038 self.monNomFichierInput=fn
1040 if not hasattr(self, 'fichierMapInput') or not self.fichierMapInput or not os.path.exists(self.fichierMapInput):
1041 self.fichierMapInput = self.__generateTempFilename(prefix = "map_run", suffix = ".map")
1042 texte=self.get_text_JDC("MAP")
1043 self.writeFile( self.fichierMapInput, txt = texte)
1045 cmd = ("map gen -t dat -n " + composant + " -i " + self.fichierMapInput + " -o " + fn)
1046 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
1047 (output, err) = p.communicate()
1051 def saveRunPSEN(self):
1056 if not(self.jdc.isvalid()):
1057 QMessageBox.critical( self, tr( "Sauvegarde de l'input impossible "),
1058 tr("Un JdC valide est necessaire pour creer un .input")
1062 print generator.plugins.has_key(self.format)
1063 if generator.plugins.has_key(self.format):
1064 # Le generateur existe on l'utilise
1065 self.generator=generator.plugins[self.format]()
1067 self.generator.gener(self.jdc)
1068 self.generator.writeDefault('')
1069 except ValueError,e:
1070 QMessageBox.critical(self, tr("Erreur a la generation"),str(e))
1071 if not self.generator.cr.estvide():
1072 self.affiche_infos(tr("Erreur a la generation"),Qt.red)
1073 QMessageBox.critical( self, tr("Erreur a la generation"),tr("EFICAS ne sait pas convertir ce JDC"))
1076 # Il n'existe pas c'est une erreur
1077 self.affiche_infos(tr("Format %s non reconnu" , self.format),Qt.red)
1078 QMessageBox.critical( self, "Format non reconnu" ,tr("EFICAS ne sait pas convertir le JDC selon le format "+ self.format))
1085 #-----------------------------------------#
1086 def cherche_Groupes(self):
1087 #-----------------------------------------#
1088 listeMA,listeNO=self.get_text_JDC("GroupMA")
1089 return listeMA,listeNO
1091 #-----------------------------------------#
1092 def cherche_Dico(self):
1093 #-----------------------------------------#
1095 format = self.appliEficas.format_fichier
1096 if generator.plugins.has_key(format):
1097 # Le generateur existe on l'utilise
1098 self.generator=generator.plugins[format]()
1099 jdc_formate=self.generator.gener(self.jdc,format='beautifie',config=self.appliEficas.CONFIGURATION)
1100 dicoCourant=self.generator.dico
1105 #-----------------------------------------#
1106 def handleAjoutGroup(self,listeGroup):
1107 #-----------------------------------------#
1110 from ajoutGroupe import handleAjoutGroupFiltre
1112 handleAjoutGroupFiltre(self,listeGroup)
1113 #print "apres handleAjoutGroupFiltre"
1118 #-----------------------------------------------------------------#
1119 def saveFile(self, path = None, saveas= 0,formatLigne="beautifie"):
1120 #-----------------------------------------------------------------#
1122 Public slot to save the text to a file.
1124 @param path directory to save the file in (string or QString)
1125 @return tuple of two values (boolean, string) giving a success indicator and
1126 the name of the saved file
1130 if not self.modified and not saveas:
1131 return (0, None) # do nothing if text wasn't changed
1134 if DictExtensions.has_key(self.appli.code) :
1135 extension=DictExtensions[self.appli.code]
1141 if self.fichier is None or saveas:
1143 path=self.CONFIGURATION.savedir
1144 bOK, fn=self.determineNomFichier(path,extension)
1145 if bOK == 0 : return (0, None)
1146 if fn == None : return (0, None)
1147 if fn== '' : return (0, None)
1149 ulfile = os.path.abspath(unicode(fn))
1150 self.appliEficas.CONFIGURATION.savedir=os.path.split(ulfile)[0]
1151 fn = unicode(QDir.toNativeSeparators(fn))
1155 if not (self.writeFile(fn,formatLigne=formatLigne)): return (0, None)
1157 self.modified = False
1158 if self.fileInfo is None or saveas:
1159 self.fileInfo = QFileInfo(self.fichier)
1160 self.fileInfo.setCaching(0)
1161 self.lastModified = self.fileInfo.lastModified()
1162 if newName is not None:
1163 self.appliEficas.addToRecentList(newName)
1164 self.tree.racine.item.getObject().nom=os.path.basename(newName)
1165 self.tree.racine.update_node_label()
1167 if self.jdc.isvalid() != 0 and hasattr(self.generator, "writeDefault"):
1168 self.generator.writeDefault(fn)
1171 self.appliEficas.addJdcInSalome( self.fichier)
1173 nouveauTitre=self.titre+" "+str(os.path.basename(self.fichier))
1174 self.appliEficas.setWindowTitle(nouveauTitre)
1176 return (1, self.fichier)
1179 #----------------------------------------------#
1180 def sauveLigneFile(self):
1181 #----------------------------------------------#
1183 return self.saveFile(formatLigne="Ligne")
1186 #----------------------------------------------#
1187 def saveFileAs(self, path = None,fileName=None):
1188 #----------------------------------------------#
1190 Public slot to save a file with a new name.
1192 @param path directory to save the file in (string or QString)
1193 @return tuple of two values (boolean, string) giving a success indicator and
1194 the name of the saved file
1196 if fileName != None :
1197 self.fichier = fileName
1198 return self.saveFile()
1199 return self.saveFile(path,1,"beautifie")
1203 #---------------------------------------------#
1204 def get_file(self,unite=None,fic_origine = ''):
1205 #---------------------------------------------#
1213 titre = tr("Choix unite %d ", unite)
1214 texte = tr("Le fichier %s contient une commande INCLUDE \n", str(fic_origine)) +"\n"
1215 texte = texte+ tr("Donnez le nom du fichier correspondant a l unite logique ") + repr(unite)
1216 labeltexte = tr('Fichier pour unite ') + repr( unite)
1218 titre = tr("Choix d'un fichier de poursuite")
1219 texte = tr("Le fichier %s contient une commande POURSUITE\n", fic_origine)
1220 texte = texte+tr('Donnez le nom du fichier dont vous \n voulez faire une poursuite')
1222 QMessageBox.information( self, titre,texte)
1223 fn = QFileDialog.getOpenFileName(self.appliEficas,
1225 self.appliEficas.CONFIGURATION.savedir)
1227 # ce retour est impose par le get_file d'I_JDC
1228 if fn== '' : return None," "
1229 if not fn : return (0, " ")
1230 if monEnvQT5 : fn=fn[0]
1232 ulfile = os.path.abspath(unicode(fn))
1233 self.appliEficas.CONFIGURATION.savedir=os.path.split(ulfile)[0]
1235 # On utilise le convertisseur defini par format_fichier
1236 source=self.get_source(ulfile)
1238 # On a reussia convertir le fichier self.ulfile
1241 # Une erreur a ete rencontree
1243 return ulfile, jdcText
1245 #-------------------------------#
1246 def updateJdc(self, itemApres,texte):
1247 #--------------------------------#
1249 etape=monItem.item.object
1251 CONTEXT.set_current_step(etape)
1252 etape.build_includeInclude(texte)
1253 self.tree.racine.build_children()
1258 #-------------------------------------#
1259 def ajoutVersionCataDsJDC(self,txt):
1260 #-------------------------------------#
1261 if not hasattr(self.readercata.cata[0],'VERSION_CATALOGUE'): return txt
1262 ligneVersion="#VERSION_CATALOGUE:"+self.readercata.cata[0].VERSION_CATALOGUE+":FIN VERSION_CATALOGUE\n"
1263 texte=txt+ligneVersion
1266 #-------------------------------------#
1267 def verifieVersionCataDuJDC(self,text):
1268 #-------------------------------------#
1270 indexDeb=text.find("#VERSION_CATALOGUE:")
1271 indexFin=text.find(":FIN VERSION_CATALOGUE")
1273 self.versionCataDuJDC="sans"
1276 self.versionCataDuJDC=text[indexDeb+19:indexFin]
1277 textJDC=text[0:indexDeb]+text[indexFin+23:-1]
1279 self.versionCata="sans"
1280 if hasattr(self.readercata.cata[0],'VERSION_CATALOGUE'): self.versionCata=self.readercata.cata[0].VERSION_CATALOGUE
1282 if self.versionCata==self.versionCataDuJDC : memeVersion=True
1283 return memeVersion,textJDC
1285 #-------------------------------#
1286 def traduitCatalogue(self,texte):
1287 #-------------------------------#
1288 nomTraducteur="traduit"+self.readercata.code+self.versionCataDuJDC+"To"+self.versionCata
1289 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"../Traducteur")))
1291 traducteur=__import__(nomTraducteur)
1292 monTraducteur=traducteur.MonTraducteur(texte)
1293 nouveauTexte=monTraducteur.traduit()
1299 #------------------------------#
1300 def verifieCHECKSUM(self,text):
1301 #------------------------------#
1302 indexDeb=text.find("#CHECKSUM:")
1305 indexFin=text.find(":FIN CHECKSUM")
1306 checkAvant=text[indexDeb:indexFin+13]
1307 textJDC=text[0:indexDeb]+text[indexFin+13:-1]
1308 checksum=self.get_checksum(textJDC)
1309 pareil=(checkAvant==checksum)
1310 return pareil, textJDC
1312 #---------------------------#
1313 def get_checksum(self,texte):
1314 #---------------------------#
1315 newtexte=texte.replace('"','\\"')
1316 commande='echo "'+newtexte+'"|md5sum'
1317 a=os.popen(commande)
1320 ligne="#CHECKSUM:"+checksum[0:-1]+":FIN CHECKSUM"
1324 #---------------------------#
1325 def _newTELEMAC(self):
1326 #---------------------------#
1327 texte="INITIALIZATION();BOUNDARY_CONDITIONS();GENERAL_PARAMETERS();PHYSICAL_PARAMETERS();NUMERICAL_PARAMETERS();"
1331 #---------------------------#
1333 #---------------------------#
1334 texte="DIRECTORY() ; PSSE_PARAMETERS() ; SIMULATION() ; sansnom=DISTRIBUTION() ; sansnom=DISTRIBUTION() ; CORRELATION() ;"
1338 #---------------------------#
1340 #---------------------------#
1341 def _newZCRACKS(self):
1342 #---------------------------#
1343 texte="MAILLAGES();REMESHING();"
1346 #---------------------------#
1347 def _newJDCCND(self):
1348 #---------------------------#
1349 extensions=tr('Fichiers Med (*.med);;''Tous les Fichiers (*)')
1351 #if self.salome == 0 :
1352 QMessageBox.information( self,
1354 tr("Veuillez selectionner un fichier Med"))
1355 QSfichier = QFileDialog.getOpenFileName(self.appliEficas,
1356 caption='Fichier Med',
1358 if monEnvQT5 : QSfichier=QSfichier[0]
1359 self.fichierMED=QSfichier
1360 from acquiertGroupes import getGroupes
1361 erreur,self.listeGroupes,self.nomMaillage,self.dicoCoord=getGroupes(self.fichierMED)
1362 if erreur != "" : print "a traiter"
1363 texteComm="COMMENTAIRE(u'Cree - fichier : "+self.fichierMED +" - Nom Maillage : "+self.nomMaillage+"');\nPARAMETRES()\n"
1369 for groupe in self.listeGroupes :
1370 if groupe[0:8]=='CURRENT_':
1371 texteSources +=groupe[8:]+"=SOURCE("
1372 texteSources +="VecteurDirecteur=(1.0,2.0,3.0,),);\n"
1373 if groupe[0:5]=='COND_': texteCond +=groupe[5:]+"=CONDUCTEUR();\n"
1374 if groupe[0:7]=='NOCOND_': texteNoCond +=groupe[7:]+"=NOCOND();\n"
1375 if groupe[0:5]=='VCUT_': texteVcut +='V_'+groupe[5:]+"=VCUT();\n"
1376 if groupe[0:3]=='ZS_': texteZs +=groupe[3:]+"=ZS();\n"
1377 texte=texteComm+texteSources+texteCond+texteNoCond+texteVcut+texteZs
1378 self.newTexteCND=texte
1383 #---------------------------#
1384 def BoutonFileSelected(self):
1385 #---------------------------#
1387 QSfichier=self.openfile.selectedFiles()[0]
1388 self.fichierMED=str(QSfichier)
1389 from acquiertGroupes import getGroupes
1390 erreur,self.listeGroupes,self.nomMaillage=getGroupes(self.fichierMED)
1391 if erreur != "" : print "a traiter"
1393 #-----------------------------
1394 def BoutonSalomePressed(self):
1395 #----------------------------
1396 Msg,self.listeGroupes=self.appliEficas.ChercheGrpMailleInSalome()
1397 self.fichierMED="A_partir_de_SMESH"
1398 self.nomMaillage="A_partir_de_SMESH"
1399 self.openfile.close()
1401 #-------------------------------------
1402 def saveSplitterSizes(self,event=None):
1403 #------------------------------------
1404 if self.inhibeSplitter : return
1405 if not hasattr(self,'splitter') : return
1406 print "______________________"
1407 print "saveSplitterSizes"
1408 print self.splitterSizes
1409 if self.splitterSizes[2] != 0 : self.oldSizeWidgetOptionnel = self.splitterSizes[2]
1410 for i in range(len(self.splitter.sizes())):
1411 self.splitterSizes[i] = self.splitter.sizes()[i]
1412 self.splitter.widget(i).resizeEvent=self.saveSplitterSizes
1413 print self.splitterSizes
1414 print "______________________"
1417 #-----------------------------------------
1418 def restoreSplitterSizes(self,nbWigdet=3):
1419 #----------------------------------------
1420 self.inhibeSplitter = 1
1422 if not(hasattr(self,'splitter')) : return
1423 newSizes=self.splitterSizes[:nbWigdet]
1424 self.splitter.setSizes(newSizes)
1425 print self.splitterSizes
1426 self.inhibeSplitter = 0
1428 #------------------------
1429 def fermeOptionnel(self):
1430 #------------------------
1431 if self.widgetOptionnel == None : return
1433 self.inhibeSplitter=1
1434 self.splitterSizes[1] = self.splitterSizes[1] + self.splitterSizes[2]
1435 if self.splitterSizes[2]!=0 : self.oldSizeWidgetOptionnel = self.splitterSizes[2]
1436 self.splitterSizes[2]=0
1438 self.widgetOptionnel.setParent(None)
1439 self.widgetOptionnel.close()
1440 self.widgetOptionnel.deleteLater()
1441 self.widgetOptionnel=None
1442 self.inhibeSplitter=0
1443 self.restoreSplitterSizes(2)
1445 #------------------------
1446 def ajoutOptionnel(self):
1447 #------------------------
1448 #print "ajoutOptionnel"
1449 #print self.splitterSizes
1450 self.splitterSizes[2] = self.oldSizeWidgetOptionnel
1451 self.splitterSizes[1] = self.splitterSizes[1] - self.splitterSizes[2]
1452 self.inhibeSplitter=0
1453 self.restoreSplitterSizes(3)
1456 #-----------------------------
1457 def getTreeIndex(self,noeud):
1458 #----------------------------
1460 if noeud in noeud.treeParent.children :
1461 indexNoeud=noeud.treeParent.children.index(noeud)
1463 if hasattr(noeud,'vraiParent') :
1465 noeudVraiParent = noeud.vraiParent
1466 while noeudVraiParent != noeud.treeParent and hasattr(noeudVraiParent,'vraiParent') :
1467 noeudVrai = noeudVraiParent
1468 noeudVraiParent = noeudVraiParent.vraiParent
1470 if noeudVraiParent == noeud.treeParent :
1471 indexNoeud=noeud.treeParent.children.index(noeudVrai)
1477 if __name__ == "__main__":
1479 name='prefs_'+prefs.code
1480 prefsCode=__import__(name)
1483 if hasattr(prefsCode,'encoding'):
1484 # Hack pour changer le codage par defaut des strings
1487 sys.setdefaultencoding(prefs.encoding)
1488 del sys.setdefaultencoding
1493 app = QApplication(sys.argv)
1494 mw = JDCEditor(None,'azAster.comm')
1495 app.setMainWidget(mw)
1496 app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
1499 res = app.exec_loop()