Salome HOME
7ab8dc62797164419a18aa4d11aa7f948a1af16e
[tools/eficas.git] / InterfaceQT4 / editor.py
1 # -*- coding: utf-8 -*-
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20
21 print "INTERFACEQT4"
22 import types,sys,os
23 import traceback
24 from PyQt4 import *
25 from PyQt4.QtGui  import *
26 from PyQt4.QtCore import *
27
28 # Modules Eficas
29
30 import convert,generator
31 from Editeur     import session
32 from Editeur     import comploader
33 from Editeur     import Objecttreeitem
34 import browser
35 import readercata
36 import qtCommun
37
38
39 VERSION_EFICAS  = "EFICAS v1.15"
40
41
42 class JDCEditor(QSplitter):
43 # -------------------------- #
44     """
45        Editeur de jdc
46     """        
47
48     def __init__ (self,appli,fichier = None, jdc = None, QWParent=None, units = None, include=0 , vm=None):          
49     #----------------------------------------------------------------------------------------------------------#
50
51         #print "fichier", fichier,"jdc",jdc,"units",units,"include",include
52         QSplitter.__init__(self, QWParent)
53         self.appliEficas = appli
54         self.appli       = appli  #---- attendu par IHM
55         self.vm          = vm
56         self.fichier     = fichier
57         self.jdc         = jdc
58         self.QWParent    = QWParent
59
60         self.test=0
61         VERSION_CODE    = session.d_env.cata
62         if appli != None :
63            self.salome =  self.appliEficas.salome
64            self.format =  self.appliEficas.format_fichier
65         else :
66            self.salome=0
67            print "dans JDC pas d appli ????????"
68
69         self.code = self.appliEficas.CONFIGURATION.code
70         self.version_code = VERSION_CODE
71         self.titre=VERSION_EFICAS + ' pour '+ self.code
72
73         self.dict_reels={}
74         self.liste_simp_reel=[]        
75         self.ihm="QT"
76         
77         import configuration
78         self.CONFIGURATION = self.appliEficas.CONFIGURATION
79         self.CONFIGStyle =   self.appliEficas.CONFIGStyle
80
81         self.sb = None
82         if hasattr(self.appliEficas,"statusBar"):
83            self.sb = self.appliEficas.statusBar()
84       
85         self.fileInfo       = None
86         self.lastModified   = 0
87         
88         self.modified   = False
89         self.isReadOnly = False
90         self.tree = None
91         self.node_selected = None
92         
93         if not hasattr( readercata, 'reader' ) :
94             readercata.reader = readercata.READERCATA( self, self.appliEficas )
95         self.readercata = readercata.reader
96         
97         #------- construction du jdc --------------
98
99         jdc_item = None
100                         
101         nouveau=0
102         if self.fichier is not None:        #  fichier jdc fourni
103             self.fileInfo = QFileInfo(self.fichier)
104             self.fileInfo.setCaching(0)
105             if jdc==None :
106                self.jdc = self.readFile(self.fichier)
107             else :
108                self.jdc=jdc
109             if units is not None:
110                self.jdc.recorded_units=units
111                self.jdc.old_recorded_units=units
112         else: 
113             if not self.jdc:                   #  nouveau jdc
114                 if not include :
115                    self.jdc = self._newJDC(units=units)
116                 else :
117                    self.jdc = self._newJDCInclude(units=units)
118                 nouveau=1
119         
120         if self.jdc:            
121             self.jdc.appli = self
122             txt_exception  = None
123             if not jdc:
124                 self.jdc.analyse()            
125                 txt_exception = self.jdc.cr.get_mess_exception()            
126             if txt_exception:
127                 self.jdc = None
128                 qApp.restoreOverrideCursor()
129                 self.affiche_infos("Erreur fatale au chargement de %s" %fichier)                
130                 QMessageBox.critical( self, "Erreur fatale au chargement d'un fichier", txt_exception)                
131             else:
132                 comploader.charger_composants("QT")
133                 jdc_item=Objecttreeitem.make_objecttreeitem( self, "nom", self.jdc )
134
135                 if (not self.jdc.isvalid()) and (not nouveau) :
136                     self.viewJdcRapport()
137         if jdc_item:                        
138             self.tree = browser.JDCTree( jdc_item,  self )
139         
140     #--------------------------------#
141     def _newJDC( self ,units = None):        
142     #--------------------------------#
143         """
144         Initialise un nouveau JDC vierge
145         """
146         CONTEXT.unset_current_step()        
147         jdc=self.readercata.cata[0].JdC( procedure="",
148                                          appli=self,
149                                          cata=self.readercata.cata,
150                                          cata_ord_dico=self.readercata.cata_ordonne_dico,
151                                          rep_mat=self.CONFIGURATION.rep_mat
152                                         )                         
153         if units is not None:
154            jdc.recorded_units=units
155            jdc.old_recorded_units=units
156         jdc.analyse()        
157         return jdc
158         
159     #--------------------------------#
160     def _newJDCInclude( self ,units = None):        
161     #--------------------------------#
162         """
163         Initialise un nouveau JDC vierge
164         """
165         import Extensions.jdc_include
166         JdC_aux=Extensions.jdc_include.JdC_include
167         CONTEXT.unset_current_step()        
168
169         jaux=self.readercata.cata[0].JdC( procedure="",
170                                appli=self,
171                                cata=self.readercata.cata,
172                                cata_ord_dico=self.readercata.cata_ordonne_dico,
173                                rep_mat=self.CONFIGURATION.rep_mat,
174                               )
175         jaux.analyse()
176
177         J=JdC_aux( procedure="",
178                    appli=self,
179                    cata=self.readercata.cata,
180                    cata_ord_dico=self.readercata.cata_ordonne_dico,
181                    jdc_pere=jaux,
182                    rep_mat=self.CONFIGURATION.rep_mat,
183                    )
184         J.analyse()
185         if units is not None:
186            J.recorded_units=units
187            J.old_recorded_units=units
188         return J
189
190     #-----------------------#
191     def readFile(self, fn):
192     #--------------------------------#
193         """
194         Public slot to read the text from a file.
195         @param fn filename to read from (string or QString)
196         """        
197         fn = unicode(fn)        
198                         
199         # ------------------------------------------------------------------------------------
200         #                         charge le JDC
201         # ------------------------------------------------------------------------------------      
202         
203         jdcName=os.path.basename(fn)
204         # Il faut convertir le contenu du fichier en fonction du format
205         if convert.plugins.has_key( self.appliEficas.format_fichier ):
206              # Le convertisseur existe on l'utilise
207              appli = self 
208              p=convert.plugins[self.appliEficas.format_fichier]()
209              p.readfile(fn)         
210              text=p.convert('exec',appli)
211              if not p.cr.estvide():                 
212                 self.affiche_infos("Erreur à la conversion")
213         else :
214             self.affiche_infos("Type de fichier non reconnu")
215             QMessageBox.critical( self, "Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")            
216             return None
217         
218         CONTEXT.unset_current_step()
219         jdc=self.readercata.cata[0].JdC(procedure=text,
220                                     appli=self,
221                                     cata=self.readercata.cata,
222                                     cata_ord_dico=self.readercata.cata_ordonne_dico,
223                                     nom=jdcName,
224                                     rep_mat=self.CONFIGURATION.rep_mat
225                                    )
226         # ----------------------------------------------------
227         #      charge le JDC fin
228         # ----------------------------------------------------
229         self.modified = False
230                         
231 #        qApp.restoreOverrideCursor()        
232         if self.fileInfo!= None : 
233            self.lastModified = self.fileInfo.lastModified()
234         else :
235            self.lastModified = 1
236         return jdc
237         
238
239     #-----------------------#
240     def get_source(self,file):
241     #-----------------------#
242         format=self.appliEficas.format_fichier
243
244         # Il faut convertir le contenu du fichier en fonction du format
245         if convert.plugins.has_key(format):
246             # Le convertisseur existe on l'utilise
247             p=convert.plugins[format]()
248             p.readfile(file)
249             text=p.convert('execnoparseur')
250             if not p.cr.estvide():
251                 self.affiche_infos("Erreur a la conversion")
252             return text
253         else:
254             # Il n'existe pas c'est une erreur
255             self.affiche_infos("Type de fichier non reconnu")
256             QMessageBox.critical( self, "Type de fichier non reconnu","EFICAS ne sait pas ouvrir ce type de fichier")            
257             return None
258
259     #----------------------------------------------#
260     def _viewText(self, txt, caption = "FILE_VIEWER"):    
261     #----------------------------------------------#
262         w = qtCommun.ViewText( self.QWParent )
263         w.setWindowTitle( caption )
264         w.setText(txt)
265         w.show()
266         
267     #-----------------------#
268     def viewJdcSource(self):        
269     #-----------------------#
270         format = self.appliEficas.format_fichier
271         f=open(self.fichier,'r')
272         texteSource=f.read()
273         f.close()
274         self._viewText(texteSource, "JDC_SOURCE")
275                 
276     #-----------------------#
277     def viewJdcPy(self):        
278     #-----------------------#
279         format = self.appliEficas.format_fichier
280         strSource = str( self.get_text_JDC(format) )       
281         self._viewText(strSource, "JDC_RESULTAT")
282                  
283     #-----------------------#
284     def viewJdcRapport(self):
285     #-----------------------#
286         strRapport = str( self.jdc.report() )
287         self._viewText(strRapport, "JDC_RAPPORT")        
288         
289     #----------------#
290     def closeIt(self):
291     #----------------#
292         """
293         Public method called by the viewmanager to finally get rid of us.
294         """
295         if self.jdc:
296             self.jdc.supprime()
297         self.close()
298     
299     #------------------------------#
300     def affiche_infos(self,message):
301     #------------------------------#
302         if self.salome :
303            if not hasattr(self.appliEficas,'MessageLabel') :
304               self.appliEficas.leLayout=QDockWindow(self.appliEficas)
305               self.appliEficas.MessageLabel = QLabel(self.appliEficas.leLayout,"MessageLabel")
306               self.appliEficas.MessageLabel.setAlignment(Qt.AlignBottom)
307               self.appliEficas.leLayout.setWidget(self.appliEficas.MessageLabel)
308               self.appliEficas.moveDockWindow(self.appliEficas.leLayout,Qt.DockBottom)
309            self.appliEficas.MessageLabel.setText(message)
310            self.appliEficas.MessageLabel.show()
311            self.appliEficas.leLayout.show()
312         if self.sb:
313             self.sb.showMessage(message)#,2000)
314
315     #------------------------------#
316     def affiche_alerte(self,titre,message):
317     #------------------------------#
318     # appele par I_MACRO_ETAPE
319         QMessageBox.information( self, titre, message)
320
321     #-------------------#
322     def init_modif(self):
323     #-------------------#
324       """
325           Met l'attribut modified a 'o' : utilise par Eficas pour savoir
326           si un JDC doit etre sauvegarde avant destruction ou non
327       """
328       self.modified = True
329
330     #---------------------------------------#
331     def chercheNoeudSelectionne(self,copie=1):
332     #---------------------------------------#
333       """
334         appele par Cut et Copy pour positionner self.node_selected
335       """
336       self.node_selected=None
337       if len(self.tree.selectedItems()) == 0 : return
338       if len(self.tree.selectedItems()) != 1 :
339           QMessageBox.information( self, 
340                       "Copie impossible",
341                       "Cette version d'EFICAS permet uniquement la copie d un seul objet")
342           return
343       self.node_selected=self.tree.selectedItems()[0]
344       if copie == 0 : return
345       if not self.node_selected.item.iscopiable():
346           QMessageBox.information( self, 
347                       "Copie impossible",
348                       "Cette version d'EFICAS ne permet pas la copie de cet Objet")
349           self.node_selected=None
350           return
351     
352     
353     #---------------------#
354     def handleEditCut(self):
355     #---------------------#
356       """
357       Stocke dans Eficas.noeud_a_editer le noeud à couper
358       """
359       self.chercheNoeudSelectionne()
360       self.QWParent.edit="couper"
361       self.QWParent.noeud_a_editer = self.node_selected      
362     
363     #-----------------------#
364     def handleEditCopy(self):
365     #-----------------------#
366       """
367       Stocke dans Eficas.noeud_a_editer le noeud a copier
368       """
369       self.chercheNoeudSelectionne()
370       self.QWParent.edit="copier"
371       self.QWParent.noeud_a_editer = self.node_selected
372     
373     #------------------------#
374     def handleEditPaste(self):
375     #------------------------#
376       """
377       Lance la copie de l'objet place dans self.QWParent.noeud_a_editer
378       Ne permet que la copie d'objets de type Commande ou MCF
379       """
380       self.chercheNoeudSelectionne()
381       index_noeud_a_couper=self.QWParent.noeud_a_editer.treeParent.children.index(self.QWParent.noeud_a_editer)
382       if self.QWParent.noeud_a_editer == None :
383           QMessageBox.information( self, 
384                       "Copie impossible",
385                       "Aucun Objet n a ete copie ou colle ")
386           return
387       try:
388          child=self.QWParent.noeud_a_editer.doPaste(self.node_selected)
389       except:
390          traceback.print_exc()
391          QMessageBox.information( self, 
392                      "Copie impossible",         
393                      "L'action de coller apres un tel objet n'est pas permise")
394          return
395     
396      
397       if child == 0:
398           if self.message != '':             
399              QMessageBox.critical( self, "Copie refusee", self.message)
400              self.message = ''
401           self.affiche_infos("Copie refusée")
402           return
403     
404       # il faut declarer le JDCDisplay_courant modifie
405       self.init_modif()
406       # suppression eventuelle du noeud selectionne
407       # si possible on renomme l objet comme le noeud couper
408
409       if self.QWParent.edit == "couper":
410          print self.QWParent.noeud_a_editer.child
411          index_ajoute=child.treeParent.children.index(child)
412          if index_ajoute <= index_noeud_a_couper :
413             index_noeud_a_couper=index_noeud_a_couper + 1
414          item=self.QWParent.noeud_a_editer.item
415          noeud_a_supprimer=self.QWParent.noeud_a_editer.treeParent.children[index_noeud_a_couper]
416          noeud_a_supprimer.delete()
417          child.item.update(item)
418          #test,mess = child.item.nomme_sd(nom)
419          child.select()
420
421       # on rend la copie a nouveau possible en liberant le flag edit
422       self.QWParent.edit="copier"
423           
424     #---------------------#
425     def getFileName(self):
426     #---------------------#
427       return self.fichier
428
429     #---------------------------#
430     def get_file_variable(self) :
431     #---------------------------#
432      titre = "Choix d'un fichier XML"
433      texte = "Le fichier contient une commande INCLUDE\n"
434      texte = texte+'Donnez le nom du fichier XML qui contient la description des variables'
435      QMessageBox.information( self, titre,texte)
436                                         
437      fichier = QFileDialog.getOpenFileName(self.appliEficas,
438                    self.appliEficas.trUtf8('Ouvrir Fichier'),
439                    self.appliEficas.CONFIGURATION.savedir,
440                    self.appliEficas.trUtf8('Wrapper Files (*.xml);;''All Files (*)'))
441      print fichier
442      return  fichier
443       
444     #----------------------------------#
445     def writeFile(self, fn, txt = None):
446     #----------------------------------#
447         """
448         Public slot to write the text to a file.
449         
450         @param fn filename to write to (string or QString)
451         @return flag indicating success
452         """
453
454         fn = unicode(fn)
455
456         if txt == None :
457             txt = self.get_text_JDC(self.appliEficas.format_fichier)
458             eol = '\n'        
459             if len(txt) >= len(eol):
460                if txt[-len(eol):] != eol:
461                   txt += eol
462             else:
463                 txt += eol        
464         try:
465             f = open(fn, 'wb')
466             f.write(txt)
467             f.close()
468             return 1
469         except IOError, why:
470             QMessageBox.critical(self, self.trUtf8('Save File'),
471                 self.trUtf8('The file <b>%1</b> could not be saved.<br>Reason: %2')
472                     .arg(unicode(fn)).arg(str(why)))
473             return 0
474
475     #-----------------------------#
476     def get_text_JDC(self,format):
477     #-----------------------------#
478       if generator.plugins.has_key(format):
479          # Le generateur existe on l'utilise
480          self.generator=generator.plugins[format]()
481          jdc_formate=self.generator.gener(self.jdc,format='beautifie')
482          if not self.generator.cr.estvide():            
483             self.affiche_infos("Erreur à la generation")
484             QMessageBox.critical( self, "Erreur a la generation","EFICAS ne sait pas convertir ce JDC")
485             return ""
486          else:
487             return jdc_formate
488       else:         
489          # Il n'existe pas c'est une erreur
490          self.affiche_infos("Format %s non reconnu" % format)
491          QMessageBox.critical( self, "Format "+format+" non reconnu","EFICAS ne sait pas convertir le JDC selon le format "+format)
492          return ""
493       
494       
495     #-----------------------------------------#
496     def saveFile(self, path = None, saveas= 0):
497     #-----------------------------------------#
498         """
499         Public slot to save the text to a file.
500         
501         @param path directory to save the file in (string or QString)
502         @return tuple of two values (boolean, string) giving a success indicator and
503             the name of the saved file
504         """        
505                 
506         if not self.modified and not saveas:
507             return (0, None)      # do nothing if text wasn't changed
508             
509         newName = None
510         if self.fichier is None or saveas:
511           if path is None: 
512              path=self.CONFIGURATION.savedir
513           selectedFilter = QString('')
514           fn = QFileDialog.getSaveFileName( self,
515                self.trUtf8("sauvegarde"), path,
516                self.trUtf8("JDC (*.comm);;" "All Files (*)"),None,
517                QFileDialog.DontConfirmOverwrite)
518           if fn.isNull(): return (0, None)
519
520           ext = QFileInfo(fn).suffix()
521           if ext.isEmpty(): fn.append(".comm")
522
523           if QFileInfo(fn).exists():
524                 abort = QMessageBox.warning(self,
525                        self.trUtf8("Sauvegarde du Fichier"),
526                        self.trUtf8("Le fichier <b>%1</b> existe deja.").arg(fn),
527                        self.trUtf8("&Ecraser"),
528                        self.trUtf8("&Abandonner"))
529                 if abort == 1 :  return (0, None)
530
531           fn = unicode(QDir.convertSeparators(fn))
532           newName = fn
533
534         else:
535             fn = self.fichier
536         
537         if self.writeFile(fn):
538             self.fichier = fn
539             self.modified  = False                        
540             if self.fileInfo is None or saveas:
541                 self.fileInfo = QFileInfo(self.fichier)
542                 self.fileInfo.setCaching(0)
543             self.lastModified = self.fileInfo.lastModified()
544             if newName is not None:
545                 self.appliEficas.addToRecentList(newName)
546                 self.tree.racine.item.getObject().nom=os.path.basename(newName)
547                 self.tree.racine.update_node_label()
548                
549             try : 
550             #if 1 :
551                fileXML = fn[:fn.rfind(".")] + '.xml'
552                self.generator.writeOpenturnsXML( fileXML )
553             except :
554             #else :
555                pass
556                
557             #PNPNPNPN A ecrire
558             try : 
559                fileSTD = fn[:fn.rfind(".")] + '.py'
560                self.generator.writeOpenturnsSTD( fileSTD )
561             except :
562                pass
563
564 #            if self.salome : 
565 #               self.QWParent.appli.addJdcInSalome( self.fichier)
566 #               if self.code == 'ASTER':
567 #                  self.QWParent.appli.createOrUpdateMesh(self)
568 #               #PN ; TODO
569 #
570             return (1, self.fichier)
571         else:
572             return (0, None)
573 #
574     #---------------------------------#
575     def saveFileAs(self, path = None):
576     #---------------------------------#
577         """
578         Public slot to save a file with a new name.
579         
580         @param path directory to save the file in (string or QString)
581         @return tuple of two values (boolean, string) giving a success indicator and
582             the name of the saved file
583         """
584         return self.saveFile(path,1)
585
586    
587         
588     #---------------------------------------------#
589     def get_file(self,unite=None,fic_origine = ''):
590     #---------------------------------------------#
591     # appele par I_JDC
592         ulfile  = None
593         jdcText = ""
594       
595         titre  = ""
596         
597         if unite :
598             titre = "Choix unite %d " %unite
599             texte = "Le fichier %s contient une commande INCLUDE \n" % fic_origine
600             texte = texte+'Donnez le nom du fichier correspondant\n à l unité logique %d' % unite
601             labeltexte = 'Fichier pour unite %d :' % unite
602         else:
603             titre = "Choix d'un fichier de poursuite"
604             texte = "Le fichier %s contient une commande %s\n" %(fic_origine,'POURSUITE')
605             texte = texte+'Donnez le nom du fichier dont vous \n voulez faire une poursuite'
606                                         
607         QMessageBox.information( self, titre,texte)
608         path=self.CONFIGURATION.savedir
609         fn = QFileDialog.getOpenFileName( self, titre,path)
610         
611         if fn.isNull(): 
612         # ce retour est impose par le get_file d'I_JDC
613            return None," "
614             
615         ulfile = os.path.abspath(unicode(fn))
616         # On utilise le convertisseur défini par format_fichier
617         source=self.get_source(ulfile)
618         if source:
619             # On a réussi à convertir le fichier self.ulfile                
620             jdcText = source
621         else:
622             # Une erreur a été rencontrée
623             jdcText = ''
624         return ulfile, jdcText
625
626         
627 if __name__=='__main__':    
628     import prefs # dans main
629     if hasattr(prefs,'encoding'):
630        # Hack pour changer le codage par defaut des strings
631        import sys
632        reload(sys)
633        sys.setdefaultencoding(prefs.encoding)
634        del sys.setdefaultencoding
635        # Fin hack
636
637 #    #CS_pbruno note: fait implicitement des trucs ces imports (grr)
638 #    import styles
639 #    import import_code
640 #    import session
641 #
642 #    # Analyse des arguments de la ligne de commande
643 #    options=session.parse(sys.argv)
644 #    code=options.code
645 #        
646     app = QApplication(sys.argv)    
647     mw = JDCEditor(None,'azAster.comm')
648     app.setMainWidget(mw)
649     app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
650     mw.show()
651             
652     res = app.exec_loop()
653     sys.exit(res)