]> SALOME platform Git repositories - samples/pylight.git/blob - src/PYLIGHTGUI/PYLIGHTGUI.py
Salome HOME
Merge branch 'V8_5_BR'
[samples/pylight.git] / src / PYLIGHTGUI / PYLIGHTGUI.py
1 # Copyright (C) 2009-2016  OPEN CASCADE
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 #  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
21 #  Date   : 13/04/2009
22 #
23 import traceback
24 from SalomePyQt import *
25 import PYLIGHT_DataModel
26 from qtsalome import *
27 import libSALOME_Swig
28
29 import os
30 import libSalomePy
31 import vtk
32
33 # Get SALOME PyQt interface
34 sgPyQt = SalomePyQt()
35 # Get SALOME Swig interface
36 sg = libSALOME_Swig.SALOMEGUI_Swig()
37
38 ################################################
39 # GUI context class
40 # Used to store actions, menus, toolbars, etc...
41 ################################################
42
43 class GUIcontext:
44
45     # constructor
46     def __init__( self ):
47         # Load File action
48         sgPyQt.createAction(dict_actions["loadfile"], "Load text File", "Load text file")
49         # Save File action
50         sgPyQt.createAction(dict_actions["savefile"], "Save text File", "Save text file")
51         # Insert Line action
52         sgPyQt.createAction(dict_actions["insertLine"], "Insert Line", "Insert new text line")
53         # Insert new line action
54         sgPyQt.createAction(dict_actions["insertLine"], "Insert Line", "Insert new line")
55         # Edit selected line action
56         sgPyQt.createAction(dict_actions["editLine"], "Edit Line", "Edit selected line")
57         # Remove selected line action
58         sgPyQt.createAction(dict_actions["removeLine"], "Remove Lines", "Remove selected lines")
59         # Clear paragraph
60         sgPyQt.createAction(dict_actions["clearParagraph"], "Clear Paragraph", "Clear selected paragraph")
61         # Clear all paragraphs
62         sgPyQt.createAction(dict_actions["clearAll"], "Clear All", "Clear all paragraphs")
63         # Display line
64         sgPyQt.createAction(dict_actions["displayLine"], "Display Line", "Display selected line")
65         # Erase line
66         sgPyQt.createAction(dict_actions["eraseLine"], "Erase Line", "Erase selected line")
67         # Separator
68         separator = sgPyQt.createSeparator()
69
70         # Get Menu 'File'
71         menuFile = sgPyQt.createMenu( "File", -1, -1 )
72         # Add actions in the menu 'File'
73         sgPyQt.createMenu( separator,                menuFile, -1, 10)
74         sgPyQt.createMenu( dict_actions["loadfile"], menuFile, 10 );
75         sgPyQt.createMenu( dict_actions["savefile"], menuFile, 10 );
76         sgPyQt.createMenu( separator,                menuFile, -1, 10)
77         # Create 'PyLight' menu 
78         menuPyLight = sgPyQt.createMenu( "PyLight", -1, -1, 50)
79         # Add actions in the menu 'PyLight'
80         sgPyQt.createMenu( dict_actions["insertLine"],  menuPyLight, 10 );
81         sgPyQt.createMenu( dict_actions["editLine"],    menuPyLight, 10 );
82         sgPyQt.createMenu( dict_actions["removeLine"],  menuPyLight, 10 );
83         sgPyQt.createMenu( separator,                   menuPyLight, -1, 10);
84         sgPyQt.createMenu( dict_actions["clearAll"],    menuPyLight, 10 );
85         sgPyQt.createMenu( separator,                   menuPyLight, -1, 10);
86         sgPyQt.createMenu( dict_actions["displayLine"], menuPyLight, 10 );
87         sgPyQt.createMenu( dict_actions["eraseLine"],   menuPyLight, 10 );
88
89         # Create DataModel
90         self.DM = PYLIGHT_DataModel.PYLIGHT_DataModel()
91
92         pass # def __init__( self )
93
94     pass # class GUIcontext
95
96 ################################################
97 # Global variables and functions
98 ################################################
99
100 ###
101 # get active study ID
102 ###
103 def _getStudyId():
104     return sgPyQt.getStudyId()
105
106 # verbosity level
107 __verbose__ = None
108
109 ###
110 # Get verbose level
111 ###
112 def verbose():
113     global __verbose__
114     if __verbose__ is None:
115         try:
116             __verbose__ = int( os.getenv( 'SALOME_VERBOSE', 0 ) )
117         except:
118             __verbose__ = 0
119             pass
120         pass
121     return __verbose__
122
123 # study-to-context map
124 __study2context__   = {}
125 # current context
126 __current_context__ = None
127
128 ###
129 # get current GUI context
130 ###
131 def _getContext():
132     global __current_context__
133     return __current_context__
134
135 ###
136 # set and return current GUI context
137 # study ID is passed as parameter
138 ###
139 def _setContext( studyID ):
140     global __study2context__, __current_context__
141     if not __study2context__.has_key(studyID):
142         __study2context__[studyID] = GUIcontext()
143         pass
144     __current_context__ = __study2context__[studyID]
145     return __current_context__
146
147 ################################################
148
149 # Create actions and menus
150 def initialize():
151     if verbose(): print "PYLIGHTGUI::initialize()"
152     return
153
154 # called when module is activated
155 # returns True if activating is successfull and False otherwise
156 def activate():
157     if verbose() : print "PYLIGHTGUI.activate() : study : %d" % _getStudyId()
158     ctx = _setContext( _getStudyId() )
159     return True
160
161 # called when module is deactivated
162 def deactivate():
163     if verbose() : print "PYLIGHTGUI.deactivate() : study : %d" % _getStudyId()
164     pass
165
166 # called when active study is changed
167 # active study ID is passed as parameter
168 def activeStudyChanged( studyID ):
169     if verbose() : print "PYLIGHTGUI.activeStudyChanged(): study : %d" % studyID
170     ctx = _setContext( _getStudyId() )
171     pass
172
173 # Process GUI action
174 def OnGUIEvent(commandID):
175     if verbose() : print "PYLIGHTGUI::OnGUIEvent : commandID = %d" % commandID
176     if dict_command.has_key( commandID ):
177         try:
178             dict_command[commandID]()
179         except:
180             traceback.print_exc()
181     else:
182        if verbose() : print "The command is not implemented: %d" % commandID
183     pass
184
185 # Customize popup menu
186 def createPopupMenu(popup, context):
187     if verbose() : print "PYLIGHTGUI.createPopupMenu(): context = %s" % context
188
189     if context != 'ObjectBrowser':
190         return
191     
192     studyId = _getStudyId()
193     ctx = _setContext( studyId )
194     selcount = sg.SelectedCount()
195     if selcount == 1:
196         entry = sg.getSelected( 0 )
197         obj = ctx.DM.getObject(entry)
198         if obj is not None:
199             if obj.getText() != "\n":
200                 # Line is selected
201                 popup.addAction(sgPyQt.action(dict_actions["editLine"]))
202                 popup.addAction(sgPyQt.action(dict_actions["removeLine"]))
203                 popup.addSeparator()
204                 popup.addAction(sgPyQt.action(dict_actions["displayLine"]))
205                 popup.addAction(sgPyQt.action(dict_actions["displayLine"]))
206                 popup.addAction(sgPyQt.action(dict_actions["eraseLine"]))
207                 pass
208             else:
209                 # Paragraph is selected
210                 popup.addAction(sgPyQt.action(dict_actions["insertLine"]))
211                 popup.addAction(sgPyQt.action(dict_actions["clearParagraph"]))
212                 pass
213             pass
214         else:
215             onlyLines = True
216             pass
217         pass # if selcount == 1
218     pass
219
220 # For saving data in the study
221 def saveFiles(prefix):
222     if verbose(): print "PYLIGHTGUI::saveFile()"
223     ctx = _setContext( _getStudyId() )
224     postfix = "PYLIGHT.txt"
225     filename = prefix+postfix
226     ctx.DM.saveFile(filename)
227     return postfix
228
229 # For restore data from the study
230 def openFiles(filelist):
231     if verbose(): print "PYLIGHTGUI::openFile()"
232     ctx = _setContext( _getStudyId() )
233     filename =  filelist[0]
234     filename.append(filelist[1])
235     ctx.DM.loadFile(filename)
236     return True
237
238 # Loading a text file
239 def loadfile():
240     ctx = _setContext( _getStudyId() )
241     aFilter = "Text files (*.txt)"
242     filename = QFileDialog.getOpenFileName(sgPyQt.getDesktop(), "Open text file", "", aFilter, "Choose a text file to open")
243
244     if isinstance(filename,tuple) and len(filename) >=2:
245        filename = filename[0]
246
247     filename = unicode(filename)
248
249     if len(filename) == 0:
250         return
251     
252     if os.access(str(filename),os.R_OK):
253         ctx.DM.loadFile(filename)
254     else:
255         QMessageBox.warning(sgPyQt.getDesktop(),
256                             "Error!",
257                             "Can not read file:\n%s"%(filename))
258         pass
259     sg.updateObjBrowser(True)
260     pass
261
262 # Saving a text file
263 def savefile():
264     ctx = _setContext( _getStudyId() )
265     aFilter = "Text files (*.txt)"
266     filename = QFileDialog.getSaveFileName(sgPyQt.getDesktop(),"Save text file", "", aFilter, "Choose a text file to save")
267
268     if isinstance(filename,tuple) and len(filename) >=2:
269         filename = filename[0]
270
271     filename = unicode(filename)
272
273     if filename.endswith(".txt") == 0:
274         filename+=".txt"
275         pass
276
277     fn = filename
278     # Get directory name and check access
279     if os.access(str(fn[:fn.rindex(os.path.sep)]), os.W_OK):
280         ctx.DM.saveFile(filename)
281     else:
282         QMessageBox.warning(sgPyQt.getDesktop(),
283                             "Error!",
284                             "Can not save file:\n%s"%(filename))
285         pass
286     pass
287
288 def insertLine():
289     '''
290     Insert new line in the selected paragraph.
291     '''
292     ctx = _setContext( _getStudyId() )
293     #Get result
294     res = QInputDialog.getText(sgPyQt.getDesktop(),
295                                "Add new line",
296                                "Enter the text",
297                                QLineEdit.Normal)
298     if not res[1]: ### user click cancel button
299         return
300     
301     text = res[0]
302     # Nb selected objects
303     selcount = sg.SelectedCount()
304     # Nb object in the Data Model
305     paragrCount = len(ctx.DM.getParagraphs())
306
307     # Create first paragraph
308     if paragrCount == 0:
309         ctx.DM.createObject()
310         # If line not empty create first line
311         if text != "\n":
312             ctx.DM.createObject(text,ctx.DM.getParagraphs()[0])
313         sg.updateObjBrowser(True)
314         return
315     # Create paragraph
316     if text == "\n":
317         ctx.DM.createObject()
318         sg.updateObjBrowser(True)
319         return
320     else:
321         if selcount == 0:
322             QMessageBox.warning(sgPyQt.getDesktop(),
323                                 'Error!',
324                                 'Please, select paragraph!')
325             return
326         if selcount == 1:
327             entry = sg.getSelected( 0 )
328             obj = ctx.DM.getObject(entry)
329             if obj is not None:
330                 # Create line
331                 if(obj.getText() == "\n"):
332                     ctx.DM.createObject(text,entry)
333                     sg.updateObjBrowser(True);
334                     return
335                 else:
336                     QMessageBox.warning(sgPyQt.getDesktop(),
337                                         'Error!',
338                                         'Please, select paragraph!')
339             elif selcount > 1:
340                 QMessageBox.warning(sgPyQt.getDesktop(),
341                                     'Error!',
342                                     'Please, select only one paragraph!')
343     pass
344         
345         
346 # Edit selected line
347 def editLine():
348     ctx = _setContext( _getStudyId() )
349     if sg.SelectedCount() == 1:
350         entry = sg.getSelected( 0 )
351         obj = ctx.DM.getObject(entry)
352         if(obj.getText() != "\n"):
353             #Get text line
354             res = QInputDialog.getText(sgPyQt.getDesktop(),
355                                        "Edit line",
356                                        "Enter the text",
357                                        QLineEdit.Normal,
358                                        PYLIGHT_DataModel.processText(obj.getText()))
359             if not res[1]: ### user click cancel button
360                 return
361             text = res[0]
362             
363             obj.setText(text)
364         else:
365             QMessageBox.information(sgPyQt.getDesktop(),
366                                     'Info',
367                                     'Please, select line!') 
368     else:
369         QMessageBox.information(sgPyQt.getDesktop(),
370                                 'Info',
371                                 'Please, select one line!')
372     sg.updateObjBrowser(True);
373     pass
374
375 # Remove selected lines
376 def removeLine():
377     ctx = _setContext( _getStudyId() )
378     selcount = sg.SelectedCount()
379     onlyLines = True
380     lines = []
381     while selcount != 0:
382         entry = sg.getSelected( selcount - 1)
383         #Check what only lines selected
384         if ctx.DM.getObject(entry).getText() == "\n":
385             onlyLines = False
386             break
387         lines.append(entry)
388         selcount = selcount-1
389         pass
390     if not onlyLines:
391         return
392     else:
393         renderer=libSalomePy.getRenderer()
394         for ln in lines:
395             actor = getActor(ln)
396             if actor is not None:
397                 renderer.RemoveActor(actor)
398                 pass
399             pass
400         ctx.DM.removeObjects(lines)
401         sg.updateObjBrowser(True)
402         pass
403     pass
404
405 # Remove all lines from all paragraphs
406 def clearAll():
407     ctx = _setContext( _getStudyId() )
408     paragraphs = ctx.DM.getParagraphs()
409     for paragr in paragraphs:
410         lines = sgPyQt.getChildren(paragr)
411         ctx.DM.removeObjects(lines)
412         renderer=libSalomePy.getRenderer()
413         for l in lines:
414             actor = getActor(l)
415             if actor is not None:
416                 renderer.RemoveActor(actor)
417                 pass
418             pass
419     sg.updateObjBrowser(True)
420     pass
421
422 # Display the selected line
423 def displayLine():
424     ctx = _setContext( _getStudyId() )
425     if sg.SelectedCount() != 1:
426         return
427     entry = sg.getSelected(0)
428     text = ctx.DM.getObject(entry).getText()
429     if text == "\n":
430         return
431     renderer=libSalomePy.getRenderer()
432     actor = getActor(entry)
433     if actor is None:
434         actor = vtk.vtkTextActor()
435         dict_actors[entry] = actor
436         pass
437     center = renderer.GetCenter()
438     actor.SetInput(str(text))
439     actor.SetPosition(center[0],center[1])
440     txtPr = vtk.vtkTextProperty()
441     txtPr.SetFontSize(30)
442     actor.SetTextProperty(txtPr)
443     for act in  dict_actors.values():
444         renderer.RemoveActor(act)
445     renderer.AddActor(actor)
446     pass
447
448 # Clear remove all lines under selected paragraph
449 def clearParagraph():
450     ctx = _setContext( _getStudyId() )
451     lines = sgPyQt.getChildren(sg.getSelected(0))
452     ctx.DM.removeObjects(lines)
453     sg.updateObjBrowser(True)
454     pass
455
456 # Erase the selected line
457 def eraseLine():
458     ctx = _setContext( _getStudyId() )
459     if sg.SelectedCount() != 1:
460         return
461     entry = sg.getSelected(0)
462     text = ctx.DM.getObject(entry).getText()
463     if text == "\n":
464         return
465     renderer=libSalomePy.getRenderer()
466     actor = getActor(entry)
467     if actor is not None:
468         renderer.RemoveActor(actor)
469         pass
470     pass
471
472 # Return vtkActor by entry
473 def getActor(entry):
474     entry = str(entry)
475     if dict_actors.has_key(entry):
476         return dict_actors[entry]
477     return None
478
479 # Define commands
480 dict_command = {
481     951 : loadfile,
482     952 : savefile,
483     961 : insertLine,
484     962 : editLine,
485     963 : removeLine,
486     964 : clearAll,
487     971 : displayLine,
488     972 : eraseLine,
489     973 : clearParagraph,
490     }
491
492 # Define actions
493 dict_actions = {
494     "loadfile"   :    951,
495     "savefile"   :    952,
496     "insertLine" :    961,
497     "editLine"   :    962,
498     "removeLine" :    963,
499     "clearAll"   :    964,
500     "displayLine":    971,
501     "eraseLine"  :    972,
502     "clearParagraph": 973,
503     }
504
505 # Define Actors
506 dict_actors = {}