]> SALOME platform Git repositories - modules/yacs.git/blob - src/pyqt/gui/Appli.py
Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / pyqt / gui / Appli.py
1 """
2 """
3 import sys,os
4 from qt import *
5 import Tree
6 import PanelManager
7 import BoxManager
8 import Icons
9 import Items
10 import adapt
11 import Item
12 import logview
13 import pilot
14 import threading
15 import time
16 import CONNECTOR
17 import catalog
18 import traceback
19 import glob
20
21 class ErrorEvent(QCustomEvent):
22   def __init__(self,caption,msg):
23     QCustomEvent.__init__(self,8888)
24     self.caption=caption
25     self.msg=msg
26   def process(self,parent):
27     QMessageBox.warning(parent,self.caption,self.msg)
28
29 class Runner(threading.Thread):
30   def __init__(self,parent,executor,proc):
31     threading.Thread.__init__(self)
32     self.parent=parent
33     self.executor=executor
34     self.proc=proc
35
36   def run(self):
37     try:
38       self.executor.RunW(self.proc,0)
39     except ValueError,ex:
40       #traceback.print_exc()
41       QApplication.postEvent(self.parent, ErrorEvent('YACS execution error',str(ex)))
42
43 class Browser(QVBox):
44   def __init__(self,parent,proc):
45     QVBox.__init__(self,parent)
46     pp=Item.adapt(proc)
47     self.proc=proc
48     self.pproc=pp
49     self.hSplitter = QSplitter(self,"hSplitter")
50     self.objectBrowser=Tree.Tree(self.hSplitter,self.onSelect,self.onDblSelect)
51     self.objectBrowser.additem(pp)
52     self.panelManager=PanelManager.PanelManager(self.hSplitter)
53     self.panelManager.setRootItem(pp)
54     self.boxManager=BoxManager.BoxManager(self.hSplitter)
55     self.boxManager.setRootItem(pp)
56     self.selected=None
57     self.executor=None
58     self.resume=0
59     self.thr=None
60     self.log=logview.LogView()
61
62   def view_log(self):
63     self.log.text.setText(self.proc.getLogger("parser").getStr())
64     self.log.show()
65
66   def onDblSelect(self,item):
67     #item is instance of Item.Item
68     pass
69
70   def onSelect(self,item):
71     #item is instance of Item.Item
72     self.selected=item
73
74   def customEvent(self,ev):
75     if ev.type() == 8888:
76       ev.process(self)
77
78   def run(self):
79     if not self.executor:
80       self.executor = pilot.ExecutorSwig()
81     if self.thr and self.thr.isAlive():
82       return
83     #continue execution mode
84     self.executor.setExecMode(0)
85     #execute it in a thread
86     self.thr = Runner(self, self.executor, self.proc)
87     #as a daemon (no need to join)
88     self.thr.setDaemon(1)
89     #start the thread
90     self.thr.start()
91     time.sleep(0.1)
92     self.resume=0
93
94   def susp(self):
95     """Suspend or resume an executing schema"""
96     if not self.executor:
97       return
98     if not self.thr.isAlive():
99       return
100
101     if self.resume:
102       #continue execution mode
103       self.executor.setExecMode(0)
104       #resume it
105       self.executor.resumeCurrentBreakPoint()
106       self.resume=0
107     else:
108       #step by step execution mode
109       self.executor.setExecMode(1)
110       self.resume=1
111
112   def step(self):
113     """Step on a paused schema"""
114     if not self.executor:
115       self.executor = pilot.ExecutorSwig()
116     if not self.thr or not self.thr.isAlive():
117       #start in step by step mode
118       self.executor.setExecMode(1)
119       self.thr = Runner(self, self.executor, self.proc)
120       self.thr.setDaemon(1)
121       self.thr.start()
122       self.resume=1
123       return
124
125     #step by step execution mode
126     self.resume=1
127     self.executor.setExecMode(1)
128     #resume it
129     self.executor.resumeCurrentBreakPoint()
130
131   def stop(self):
132     """Stop the schema"""
133     if not self.executor:
134       return
135     if not self.thr.isAlive():
136       return
137     self.executor.setExecMode(1)
138     self.executor.waitPause()
139     self.executor.resumeCurrentBreakPoint()
140     #self.executor.stopExecution()
141
142 class Appli(QMainWindow):
143   """
144       Appli()
145       Cree la fenetre principale de l'interface utilisateur
146   """
147   def __init__(self):
148     QMainWindow.__init__(self)
149     self.createWidgets()
150     self.initActions()
151     self.initMenus()
152     self.initToolbar()
153     self.initStatusbar()
154     self.initYACS()
155
156   def createWidgets(self):
157     self.tabWidget = QTabWidget(self)
158     self.currentPanel=None
159     self.connect(self.tabWidget, SIGNAL('currentChanged(QWidget *)'),self.handlePanelChanged)
160     self.setCentralWidget(self.tabWidget)
161     self.resize(800,600)
162
163   def handlePanelChanged(self,panel):
164     self.currentPanel=panel
165
166   def initActions(self):
167     self.actions = []
168
169     self.newAct=QAction('New', QIconSet(Icons.get_image("new")), '&New',
170                           QKeySequence("CTRL+N"),self)
171     self.newAct.setStatusTip('Open an empty editor window')
172     self.newAct.setWhatsThis( """<b>New</b>"""
173             """<p>An empty editor window will be created.</p>""")
174     self.newAct.connect(self.newAct,SIGNAL('activated()'), self.newProc)
175     self.actions.append(self.newAct)
176
177     self.prefAct=QAction('Preferences',QIconSet(Icons.get_image("configure.png")),'&Preferences...',
178                            0, self)
179     self.prefAct.setStatusTip('Set the prefered configuration')
180     self.prefAct.setWhatsThis("""<b>Preferences</b>"""
181                               """<p>Set the configuration items of the application"""
182                               """ with your prefered values.</p>""")
183     self.prefAct.connect(self.prefAct,SIGNAL('activated()'), self.handlePreferences)
184     self.actions.append(self.prefAct)
185
186     self.runAct=QAction('Run',QIconSet(Icons.get_image("run.png")),'&Run',0,self)
187     self.runAct.connect(self.runAct,SIGNAL('activated()'), self.run)
188     self.runAct.setStatusTip('Run the selected schema')
189     self.actions.append(self.runAct)
190
191     self.suspAct=QAction('Suspend/resume',QIconSet(Icons.get_image("suspend-resume.gif")),'&Suspend/resume',0,self)
192     self.suspAct.connect(self.suspAct,SIGNAL('activated()'), self.susp)
193     self.suspAct.setStatusTip('Suspend/resume the selected schema')
194     self.actions.append(self.suspAct)
195
196     self.stepAct=QAction('Step',QIconSet(Icons.get_image("steps.png")),'&Step',0,self)
197     self.stepAct.connect(self.stepAct,SIGNAL('activated()'), self.step)
198     self.stepAct.setStatusTip('Step the selected schema')
199     self.actions.append(self.stepAct)
200
201     self.stopAct=QAction('Stop',QIconSet(Icons.get_image("kill.png")),'&Stop',0,self)
202     self.stopAct.connect(self.stopAct,SIGNAL('activated()'), self.stop)
203     self.stopAct.setStatusTip('Stop the selected schema')
204     self.actions.append(self.stopAct)
205
206     self.cataToolAct=QAction('Catalog Tool',0,self,"catatool")
207     self.cataToolAct.connect(self.cataToolAct,SIGNAL('activated()'), self.cata_tool)
208     self.actions.append(self.cataToolAct)
209
210   def initMenus(self):
211     menubar = self.menuBar()
212
213     #menu file
214     self.fileMenu=QPopupMenu(self)
215     self.newAct.addTo(self.fileMenu)
216     self.fileMenu.insertItem("&Open", self.openFile)
217     self.fileMenu.insertItem("&Open Salome", self.openSalomeFile)
218     self.loadersMenu = QPopupMenu(self)
219     self.fileMenu.insertItem("Loaders", self.loadersMenu)
220     self.loaders=[]
221     for file in glob.glob("/local/chris/SALOME2/SUPERV/YACS/BR_CC/YACS_SRC/src/pyqt/*loader.py"):
222       d,f=os.path.split(file)
223       name=f[:-9]
224       def call_loader(event,obj=self,file=file):
225         obj.openFileWithLoader(file)
226       self.loaders.append(call_loader)
227       self.loadersMenu.insertItem(name, call_loader)
228     menubar.insertItem('&File',self.fileMenu)
229
230     #menu settings
231     self.settingsMenu = QPopupMenu(self)
232     menubar.insertItem('&Settings', self.settingsMenu)
233     self.settingsMenu.insertTearOffHandle()
234     self.prefAct.addTo(self.settingsMenu)
235
236     #menu Edit
237     self.editMenu = QPopupMenu(self)
238     self.editMenu.insertItem("&Add node", self.addNode)
239     menubar.insertItem('&Edit', self.editMenu)
240
241     #menu Canvas
242     #sous menu layout
243     self.layoutMenu = QPopupMenu(self)
244     self.layoutMenu.insertItem("&Left Right", self.LR)
245     self.layoutMenu.insertItem("Right Left", self.RL)
246     self.layoutMenu.insertItem("Top Bottom", self.TB)
247     self.layoutMenu.insertItem("Bottom Top", self.BT)
248     self.canvasMenu = QPopupMenu(self)
249     self.canvasMenu.insertItem("&Zoom in", self.zoomIn)
250     self.canvasMenu.insertItem("Zoom &out", self.zoomOut)
251     self.canvasMenu.insertItem("Layout", self.layoutMenu)
252     self.canvasMenu.insertItem("Ortholinks", self.orthoLinks)
253     self.canvasMenu.insertItem("Clearlinks", self.clearLinks)
254     self.canvasMenu.insertItem("&Update", self.updateCanvas)
255     menubar.insertItem('&Canvas', self.canvasMenu)
256
257     #menu window
258     self.windowMenu = QPopupMenu(self)
259     self.cataToolAct.addTo(self.windowMenu)
260     self.windowMenu.insertItem("&Log", self.view_log)
261     menubar.insertItem('&Window', self.windowMenu)
262     self.connect(self.windowMenu, SIGNAL('aboutToShow()'), self.handleWindowMenu)
263
264     #menu help
265     self.help=QPopupMenu(self)
266     menubar.insertItem('&Help',self.help)
267     self.help.insertItem('&About',self.about,Qt.Key_F1)
268     self.help.insertItem('About &Qt',self.aboutQt)
269
270   def initYACS(self):
271     import pilot
272     import loader
273     import salomeloader
274     self.runtime= pilot.getRuntime()
275     self.loader = loader.YACSLoader()
276     self.executor = pilot.ExecutorSwig()
277     self.salomeloader=salomeloader.SalomeLoader()
278     self.loader.registerProcCataLoader()
279
280   def openSalomeFile(self):
281     fn = QFileDialog.getOpenFileName(QString.null,QString.null,self)
282     if fn.isEmpty():
283       self.statusBar().message('Loading aborted',2000)
284       return
285     fileName = str(fn)
286     proc=self.salomeloader.load(fileName)
287     logger=proc.getLogger("parser")
288     if logger.hasErrors():
289       self.logFile=logview.LogView()
290       self.logFile.text.setText(logger.getStr())
291       self.logFile.show()
292
293     panel=Browser(self.tabWidget,proc)
294     self.currentPanel=panel
295     self.tabWidget.addTab( panel,os.path.basename(fileName))
296     self.tabWidget.showPage(panel)
297
298   def openFile(self):
299     fn = QFileDialog.getOpenFileName(QString.null,QString.null,self)
300     if fn.isEmpty():
301       self.statusBar().message('Loading aborted',2000)
302       return
303     fileName = str(fn)
304     proc=self.loader.load(fileName)
305     logger=proc.getLogger("parser")
306     if logger.hasErrors():
307       self.logFile=logview.LogView()
308       self.logFile.text.setText(logger.getStr())
309       self.logFile.show()
310
311     panel=Browser(self.tabWidget,proc)
312     self.currentPanel=panel
313     self.tabWidget.addTab( panel,os.path.basename(fileName))
314     self.tabWidget.showPage(panel)
315
316   def newProc(self):
317     r=pilot.getRuntime()
318     proc=r.createProc("pr")
319     panel=Browser(self.tabWidget,proc)
320     self.currentPanel=panel
321     self.tabWidget.addTab( panel,proc.getName())
322     self.tabWidget.showPage(panel)
323
324   def openFileWithLoader(self,file):
325     d,f=os.path.split(file)
326     sys.path.insert(0,d)
327     module=__import__(os.path.splitext(f)[0])
328     del sys.path[0]
329     loader=module.Loader()
330
331     fn = QFileDialog.getOpenFileName(QString.null,QString.null,self)
332     if fn.isEmpty():
333       self.statusBar().message('Loading aborted',2000)
334       return
335     fileName = str(fn)
336     proc=loader.load(fileName)
337     logger=proc.getLogger("parser")
338     if logger.hasErrors():
339       self.logFile=logview.LogView()
340       self.logFile.text.setText(logger.getStr())
341       self.logFile.show()
342
343     panel=Browser(self.tabWidget,proc)
344     self.currentPanel=panel
345     self.tabWidget.addTab( panel,os.path.basename(fileName))
346     self.tabWidget.showPage(panel)
347
348   def cata_tool(self):
349     self.catalogTool=catalog.CatalogTool(self)
350     self.catalogTool.show()
351     return
352
353   def view_log(self):
354     if self.currentPanel:
355       self.currentPanel.view_log()
356
357   def LR(self,*args ):self.rankdir("LR")
358   def RL(self,*args ):self.rankdir("RL")
359   def TB(self,*args ):self.rankdir("TB")
360   def BT(self,*args ):self.rankdir("BT")
361
362   def rankdir(self,orient):
363     if self.currentPanel and self.currentPanel.panelManager.visible:
364       self.currentPanel.panelManager.visible.layout(orient)
365
366   def updateCanvas(self):
367     if self.currentPanel.selected:#item selected
368       if isinstance(self.currentPanel.selected,Items.ItemComposedNode):
369         #can update
370         self.currentPanel.selected.graph.editor.updateCanvas()
371
372   def addNode(self,node):
373     if self.currentPanel and self.currentPanel.selected:#item selected
374       if isinstance(self.currentPanel.selected,Items.ItemComposedNode):
375         #can add node
376         self.currentPanel.selected.addNode(node)
377
378   def zoomIn(self):
379     if self.currentPanel and self.currentPanel.panelManager.visible:
380       if isinstance(self.currentPanel.panelManager.visible,Items.ItemComposedNode):
381         #we can zoom
382         self.currentPanel.panelManager.visible.graph.editor.zoomIn()
383
384   def zoomOut(self):
385     if self.currentPanel and self.currentPanel.panelManager.visible:
386       if isinstance(self.currentPanel.panelManager.visible,Items.ItemComposedNode):
387         #we can unzoom 
388         self.currentPanel.panelManager.visible.graph.editor.zoomOut()
389
390   def orthoLinks(self):
391     if self.currentPanel and self.currentPanel.panelManager.visible:
392       if isinstance(self.currentPanel.panelManager.visible,Items.ItemComposedNode):
393         #it is a composed node with a graph
394         self.currentPanel.panelManager.visible.graph.orthoLinks()
395
396   def clearLinks(self):
397     if self.currentPanel and self.currentPanel.panelManager.visible:
398       if isinstance(self.currentPanel.panelManager.visible,Items.ItemComposedNode):
399         #it is a composed node with a graph
400         self.currentPanel.panelManager.visible.graph.clearLinks()
401
402   def handlePreferences(self):
403     pass
404
405   def handleWindowMenu(self):
406     pass
407
408   def about(self):
409     QMessageBox.about(self,'YACS browser GUI', 'YACS browser GUI')
410
411   def aboutQt(self):
412     QMessageBox.aboutQt(self,'YACS browser GUI')
413
414   def run(self):
415     if self.currentPanel:
416       self.currentPanel.run()
417
418   def susp(self):
419     if self.currentPanel:
420       self.currentPanel.susp()
421
422   def step(self):
423     if self.currentPanel:
424       self.currentPanel.step()
425
426   def stop(self):
427     if self.currentPanel:
428       self.currentPanel.stop()
429
430   def initToolbar(self):
431     tb = QToolBar(self)
432     self.newAct.addTo(tb)
433     self.runAct.addTo(tb)
434     self.suspAct.addTo(tb)
435     self.stepAct.addTo(tb)
436     self.stopAct.addTo(tb)
437     self.toolbars={}
438     self.toolbars['File']=tb
439
440   def initStatusbar(self):
441     sb = self.statusBar()
442     self.SBfile=QLabel(sb)
443     sb.addWidget(self.SBfile)
444     QWhatsThis.add(self.SBfile,
445                    """<p>Partie de la statusbar qui donne le nom"""
446                    """du fichier courant. </p>""")
447     self.SBfile.setText("")
448
449
450 if __name__ == "__main__":
451   from Item import Item
452   app = QApplication(sys.argv)
453   t=Appli()
454   t.objectBrowser.additem(Item("item1"))
455   n=t.objectBrowser.additem(Item("item2"))
456   n.additem(Item("item3"))
457   app.setMainWidget(t)
458   t.show()
459   app.exec_loop()
460
461