]> SALOME platform Git repositories - samples/pylight.git/blob - src/PYLIGHTGUI/PYLIGHTGUI.py
Salome HOME
Porting to Python 3 (1st draft)
[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 studyID not in __study2context__:
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 commandID in dict_command:
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     if len(filename) == 0:
248         return
249     
250     if os.access(str(filename),os.R_OK):
251         ctx.DM.loadFile(filename)
252     else:
253         QMessageBox.warning(sgPyQt.getDesktop(),
254                             "Error!",
255                             "Can not read file:\n%s"%(filename))
256         pass
257     sg.updateObjBrowser(True)
258     pass
259
260 # Saving a text file
261 def savefile():
262     ctx = _setContext( _getStudyId() )
263     aFilter = "Text files (*.txt)"
264     filename = QFileDialog.getSaveFileName(sgPyQt.getDesktop(),"Save text file", "", aFilter, "Choose a text file to save")
265
266     if isinstance(filename,tuple) and len(filename) >=2:
267         filename = filename[0]
268
269     if filename.endswith(".txt") == 0:
270         filename+=".txt"
271         pass
272
273     fn = filename
274     # Get directory name and check access
275     if os.access(str(fn[:fn.rindex(os.path.sep)]), os.W_OK):
276         ctx.DM.saveFile(filename)
277     else:
278         QMessageBox.warning(sgPyQt.getDesktop(),
279                             "Error!",
280                             "Can not save file:\n%s"%(filename))
281         pass
282     pass
283
284 def insertLine():
285     '''
286     Insert new line in the selected paragraph.
287     '''
288     ctx = _setContext( _getStudyId() )
289     #Get result
290     res = QInputDialog.getText(sgPyQt.getDesktop(),
291                                "Add new line",
292                                "Enter the text",
293                                QLineEdit.Normal)
294     if not res[1]: ### user click cancel button
295         return
296     
297     text = res[0]
298     # Nb selected objects
299     selcount = sg.SelectedCount()
300     # Nb object in the Data Model
301     paragrCount = len(ctx.DM.getParagraphs())
302
303     # Create first paragraph
304     if paragrCount == 0:
305         ctx.DM.createObject()
306         # If line not empty create first line
307         if text != "\n":
308             ctx.DM.createObject(text,ctx.DM.getParagraphs()[0])
309         sg.updateObjBrowser(True)
310         return
311     # Create paragraph
312     if text == "\n":
313         ctx.DM.createObject()
314         sg.updateObjBrowser(True)
315         return
316     else:
317         if selcount == 0:
318             QMessageBox.warning(sgPyQt.getDesktop(),
319                                 'Error!',
320                                 'Please, select paragraph!')
321             return
322         if selcount == 1:
323             entry = sg.getSelected( 0 )
324             obj = ctx.DM.getObject(entry)
325             if obj is not None:
326                 # Create line
327                 if(obj.getText() == "\n"):
328                     ctx.DM.createObject(text,entry)
329                     sg.updateObjBrowser(True);
330                     return
331                 else:
332                     QMessageBox.warning(sgPyQt.getDesktop(),
333                                         'Error!',
334                                         'Please, select paragraph!')
335             elif selcount > 1:
336                 QMessageBox.warning(sgPyQt.getDesktop(),
337                                     'Error!',
338                                     'Please, select only one paragraph!')
339     pass
340         
341         
342 # Edit selected line
343 def editLine():
344     ctx = _setContext( _getStudyId() )
345     if sg.SelectedCount() == 1:
346         entry = sg.getSelected( 0 )
347         obj = ctx.DM.getObject(entry)
348         if(obj is not None and obj.getText() != "\n"):
349             #Get text line
350             res = QInputDialog.getText(sgPyQt.getDesktop(),
351                                        "Edit line",
352                                        "Enter the text",
353                                        QLineEdit.Normal,
354                                        PYLIGHT_DataModel.processText(obj.getText()))
355             if not res[1]: ### user click cancel button
356                 return
357             text = res[0]
358             
359             obj.setText(text)
360         else:
361             QMessageBox.information(sgPyQt.getDesktop(),
362                                     'Info',
363                                     'Please, select line!') 
364     else:
365         QMessageBox.information(sgPyQt.getDesktop(),
366                                 'Info',
367                                 'Please, select one line!')
368     sg.updateObjBrowser(True);
369     pass
370
371 # Remove selected lines
372 def removeLine():
373     ctx = _setContext( _getStudyId() )
374     selcount = sg.SelectedCount()
375     onlyLines = True
376     lines = []
377     while selcount != 0:
378         entry = sg.getSelected( selcount - 1)
379         #Check what only lines selected
380         obj = ctx.DM.getObject(entry)
381         if obj is None:
382             continue
383         if obj.getText() == "\n":
384             onlyLines = False
385             break
386         lines.append(entry)
387         selcount = selcount-1
388         pass
389     if not onlyLines:
390         return
391     else:
392         renderer=libSalomePy.getRenderer()
393         for ln in lines:
394             actor = getActor(ln)
395             if actor is not None:
396                 renderer.RemoveActor(actor)
397                 pass
398             pass
399         ctx.DM.removeObjects(lines)
400         sg.updateObjBrowser(True)
401         pass
402     pass
403
404 # Remove all lines from all paragraphs
405 def clearAll():
406     ctx = _setContext( _getStudyId() )
407     paragraphs = ctx.DM.getParagraphs()
408     for paragr in paragraphs:
409         lines = sgPyQt.getChildren(paragr)
410         ctx.DM.removeObjects(lines)
411         renderer=libSalomePy.getRenderer()
412         for l in lines:
413             actor = getActor(l)
414             if actor is not None:
415                 renderer.RemoveActor(actor)
416                 pass
417             pass
418     sg.updateObjBrowser(True)
419     pass
420
421 # Display the selected line
422 def displayLine():
423     ctx = _setContext( _getStudyId() )
424     if sg.SelectedCount() != 1:
425         return
426     entry = sg.getSelected(0)
427     obj = ctx.DM.getObject(entry)
428     if obj is None:
429         QMessageBox.information(sgPyQt.getDesktop(),
430                                 'Info',
431                                 'Please, select line!')
432         return
433     text = obj.getText()
434     if text == "\n":
435         return
436     renderer=libSalomePy.getRenderer()
437     actor = getActor(entry)
438     if actor is None:
439         actor = vtk.vtkTextActor()
440         dict_actors[entry] = actor
441         pass
442     center = renderer.GetCenter()
443     actor.SetInput(str(text))
444     actor.SetPosition(center[0],center[1])
445     txtPr = vtk.vtkTextProperty()
446     txtPr.SetFontSize(30)
447     actor.SetTextProperty(txtPr)
448     for act in  list(dict_actors.values()):
449         renderer.RemoveActor(act)
450     renderer.AddActor(actor)
451     pass
452
453 # Clear remove all lines under selected paragraph
454 def clearParagraph():
455     ctx = _setContext( _getStudyId() )
456     lines = sgPyQt.getChildren(sg.getSelected(0))
457     ctx.DM.removeObjects(lines)
458     sg.updateObjBrowser(True)
459     pass
460
461 # Erase the selected line
462 def eraseLine():
463     ctx = _setContext( _getStudyId() )
464     if sg.SelectedCount() != 1:
465         return
466     entry = sg.getSelected(0)
467     obj = ctx.DM.getObject(entry)
468     if obj is None:
469         QMessageBox.information(sgPyQt.getDesktop(),
470                                 'Info',
471                                 'Please, select line!')
472         return
473     text = obj.getText()
474     if text == "\n":
475         return
476     renderer=libSalomePy.getRenderer()
477     actor = getActor(entry)
478     if actor is not None:
479         renderer.RemoveActor(actor)
480         pass
481     pass
482
483 # Return vtkActor by entry
484 def getActor(entry):
485     entry = str(entry)
486     if entry in dict_actors:
487         return dict_actors[entry]
488     return None
489
490 # Define commands
491 dict_command = {
492     951 : loadfile,
493     952 : savefile,
494     961 : insertLine,
495     962 : editLine,
496     963 : removeLine,
497     964 : clearAll,
498     971 : displayLine,
499     972 : eraseLine,
500     973 : clearParagraph,
501     }
502
503 # Define actions
504 dict_actions = {
505     "loadfile"   :    951,
506     "savefile"   :    952,
507     "insertLine" :    961,
508     "editLine"   :    962,
509     "removeLine" :    963,
510     "clearAll"   :    964,
511     "displayLine":    971,
512     "eraseLine"  :    972,
513     "clearParagraph": 973,
514     }
515
516 # Define Actors
517 dict_actors = {}