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