]> SALOME platform Git repositories - samples/pylight.git/blob - src/PYLIGHTGUI/PYLIGHTGUI.py
Salome HOME
Merge Python 3 porting.
[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 # data model
44 __data_model__ = None
45
46 class GUIcontext:
47
48     # constructor
49     def __init__( self ):
50         global __data_model__
51         # Load File action
52         sgPyQt.createAction(dict_actions["loadfile"], "Load text File", "Load text file")
53         # Save File action
54         sgPyQt.createAction(dict_actions["savefile"], "Save text File", "Save text file")
55         # Insert Line action
56         sgPyQt.createAction(dict_actions["insertLine"], "Insert Line", "Insert new text line")
57         # Insert new line action
58         sgPyQt.createAction(dict_actions["insertLine"], "Insert Line", "Insert new line")
59         # Edit selected line action
60         sgPyQt.createAction(dict_actions["editLine"], "Edit Line", "Edit selected line")
61         # Remove selected line action
62         sgPyQt.createAction(dict_actions["removeLine"], "Remove Lines", "Remove selected lines")
63         # Clear paragraph
64         sgPyQt.createAction(dict_actions["clearParagraph"], "Clear Paragraph", "Clear selected paragraph")
65         # Clear all paragraphs
66         sgPyQt.createAction(dict_actions["clearAll"], "Clear All", "Clear all paragraphs")
67         # Display line
68         sgPyQt.createAction(dict_actions["displayLine"], "Display Line", "Display selected line")
69         # Erase line
70         sgPyQt.createAction(dict_actions["eraseLine"], "Erase Line", "Erase selected line")
71         # Separator
72         separator = sgPyQt.createSeparator()
73
74         # Get Menu 'File'
75         menuFile = sgPyQt.createMenu( "File", -1, -1 )
76         # Add actions in the menu 'File'
77         sgPyQt.createMenu( separator,                menuFile, -1, 10)
78         sgPyQt.createMenu( dict_actions["loadfile"], menuFile, 10 );
79         sgPyQt.createMenu( dict_actions["savefile"], menuFile, 10 );
80         sgPyQt.createMenu( separator,                menuFile, -1, 10)
81         # Create 'PyLight' menu 
82         menuPyLight = sgPyQt.createMenu( "PyLight", -1, -1, 50)
83         # Add actions in the menu 'PyLight'
84         sgPyQt.createMenu( dict_actions["insertLine"],  menuPyLight, 10 );
85         sgPyQt.createMenu( dict_actions["editLine"],    menuPyLight, 10 );
86         sgPyQt.createMenu( dict_actions["removeLine"],  menuPyLight, 10 );
87         sgPyQt.createMenu( separator,                   menuPyLight, -1, 10);
88         sgPyQt.createMenu( dict_actions["clearAll"],    menuPyLight, 10 );
89         sgPyQt.createMenu( separator,                   menuPyLight, -1, 10);
90         sgPyQt.createMenu( dict_actions["displayLine"], menuPyLight, 10 );
91         sgPyQt.createMenu( dict_actions["eraseLine"],   menuPyLight, 10 );
92
93         # Create DataModel
94         if __data_model__ is None:
95             __data_model__ = PYLIGHT_DataModel.PYLIGHT_DataModel()
96             pass
97             
98         pass # def __init__( self )
99
100     pass # class GUIcontext
101
102 ################################################
103 # Global variables and functions
104 ################################################
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 ################################################
124
125 # Create actions and menus
126 def initialize():
127     if verbose(): print("PYLIGHTGUI::initialize()")
128     return
129
130 # called when module is activated
131 # returns True if activating is successfull and False otherwise
132 def activate():
133     if verbose() : print("PYLIGHTGUI.activate()")
134     GUIcontext()
135     return True
136
137 # called when module is deactivated
138 def deactivate():
139     if verbose() : print("PYLIGHTGUI.deactivate()")
140     pass
141
142 # Process GUI action
143 def OnGUIEvent(commandID):
144     if verbose() : print("PYLIGHTGUI::OnGUIEvent : commandID = %d" % commandID)
145     if commandID in dict_command:
146         try:
147             dict_command[commandID]()
148         except:
149             traceback.print_exc()
150     else:
151        if verbose() : print("The command is not implemented: %d" % commandID)
152     pass
153
154 # Customize popup menu
155 def createPopupMenu(popup, context):
156     global __data_model__
157     if verbose() : print("PYLIGHTGUI.createPopupMenu(): context = %s" % context)
158
159     if context != 'ObjectBrowser':
160         return
161     
162     selcount = sg.SelectedCount()
163     if selcount == 1:
164         entry = sg.getSelected( 0 )
165         obj = __data_model__.getObject(entry)
166         if obj is not None:
167             if obj.getText() != "\n":
168                 # Line is selected
169                 popup.addAction(sgPyQt.action(dict_actions["editLine"]))
170                 popup.addAction(sgPyQt.action(dict_actions["removeLine"]))
171                 popup.addSeparator()
172                 popup.addAction(sgPyQt.action(dict_actions["displayLine"]))
173                 popup.addAction(sgPyQt.action(dict_actions["displayLine"]))
174                 popup.addAction(sgPyQt.action(dict_actions["eraseLine"]))
175                 pass
176             else:
177                 # Paragraph is selected
178                 popup.addAction(sgPyQt.action(dict_actions["insertLine"]))
179                 popup.addAction(sgPyQt.action(dict_actions["clearParagraph"]))
180                 pass
181             pass
182         else:
183             onlyLines = True
184             pass
185         pass # if selcount == 1
186     pass
187
188 # For saving data in the study
189 def saveFiles(prefix):
190     global __data_model__
191     if verbose(): print("PYLIGHTGUI::saveFile()")
192     postfix = "PYLIGHT.txt"
193     filename = prefix+postfix
194     __data_model__.saveFile(filename)
195     return postfix
196
197 # For restore data from the study
198 def openFiles(filelist):
199     global __data_model__
200     if verbose(): print("PYLIGHTGUI::openFile()")
201     filename =  filelist[0]
202     filename.append(filelist[1])
203     __data_model__.loadFile(filename)
204     return True
205
206 # Loading a text file
207 def loadfile():
208     global __data_model__
209     aFilter = "Text files (*.txt)"
210     filename = QFileDialog.getOpenFileName(sgPyQt.getDesktop(), "Open text file", "", aFilter, "Choose a text file to open")
211
212     if isinstance(filename,tuple) and len(filename) >=2:
213        filename = filename[0]
214
215     if len(filename) == 0:
216         return
217     
218     if os.access(str(filename),os.R_OK):
219         __data_model__.loadFile(filename)
220     else:
221         QMessageBox.warning(sgPyQt.getDesktop(),
222                             "Error!",
223                             "Can not read file:\n%s"%(filename))
224         pass
225     sg.updateObjBrowser()
226     pass
227
228 # Saving a text file
229 def savefile():
230     global __data_model__
231     aFilter = "Text files (*.txt)"
232     filename = QFileDialog.getSaveFileName(sgPyQt.getDesktop(),"Save text file", "", aFilter, "Choose a text file to save")
233
234     if isinstance(filename,tuple) and len(filename) >=2:
235         filename = filename[0]
236
237     if filename.endswith(".txt") == 0:
238         filename+=".txt"
239         pass
240
241     fn = filename
242     # Get directory name and check access
243     if os.access(str(fn[:fn.rindex(os.path.sep)]), os.W_OK):
244         __data_model__.saveFile(filename)
245     else:
246         QMessageBox.warning(sgPyQt.getDesktop(),
247                             "Error!",
248                             "Can not save file:\n%s"%(filename))
249         pass
250     pass
251
252 def insertLine():
253     '''
254     Insert new line in the selected paragraph.
255     '''
256     global __data_model__
257     #Get result
258     res = QInputDialog.getText(sgPyQt.getDesktop(),
259                                "Add new line",
260                                "Enter the text",
261                                QLineEdit.Normal)
262     if not res[1]: ### user click cancel button
263         return
264     
265     text = res[0]
266     # Nb selected objects
267     selcount = sg.SelectedCount()
268     # Nb object in the Data Model
269     paragrCount = len(__data_model__.getParagraphs())
270
271     # Create first paragraph
272     if paragrCount == 0:
273         __data_model__.createObject()
274         # If line not empty create first line
275         if text != "\n":
276             __data_model__.createObject(text,__data_model__.getParagraphs()[0])
277         sg.updateObjBrowser()
278         return
279     # Create paragraph
280     if text == "\n":
281         __data_model__.createObject()
282         sg.updateObjBrowser()
283         return
284     else:
285         if selcount == 0:
286             QMessageBox.warning(sgPyQt.getDesktop(),
287                                 'Error!',
288                                 'Please, select paragraph!')
289             return
290         if selcount == 1:
291             entry = sg.getSelected( 0 )
292             obj = __data_model__.getObject(entry)
293             if obj is not None:
294                 # Create line
295                 if(obj.getText() == "\n"):
296                     __data_model__.createObject(text,entry)
297                     sg.updateObjBrowser();
298                     return
299                 else:
300                     QMessageBox.warning(sgPyQt.getDesktop(),
301                                         'Error!',
302                                         'Please, select paragraph!')
303             elif selcount > 1:
304                 QMessageBox.warning(sgPyQt.getDesktop(),
305                                     'Error!',
306                                     'Please, select only one paragraph!')
307     pass
308         
309         
310 # Edit selected line
311 def editLine():
312     global __data_model__
313     if sg.SelectedCount() == 1:
314         entry = sg.getSelected( 0 )
315         obj = __data_model__.getObject(entry)
316         if(obj is not None and obj.getText() != "\n"):
317             #Get text line
318             res = QInputDialog.getText(sgPyQt.getDesktop(),
319                                        "Edit line",
320                                        "Enter the text",
321                                        QLineEdit.Normal,
322                                        PYLIGHT_DataModel.processText(obj.getText()))
323             if not res[1]: ### user click cancel button
324                 return
325             text = res[0]
326             
327             obj.setText(text)
328         else:
329             QMessageBox.information(sgPyQt.getDesktop(),
330                                     'Info',
331                                     'Please, select line!') 
332     else:
333         QMessageBox.information(sgPyQt.getDesktop(),
334                                 'Info',
335                                 'Please, select one line!')
336     sg.updateObjBrowser();
337     pass
338
339 # Remove selected lines
340 def removeLine():
341     global __data_model__
342     selcount = sg.SelectedCount()
343     onlyLines = True
344     lines = []
345     while selcount != 0:
346         entry = sg.getSelected( selcount - 1)
347         #Check what only lines selected
348         obj = __data_model__.getObject(entry)
349         if obj is None:
350             continue
351         if obj.getText() == "\n":
352             onlyLines = False
353             break
354         lines.append(entry)
355         selcount = selcount-1
356         pass
357     if not onlyLines:
358         return
359     else:
360         renderer=libSalomePy.getRenderer()
361         for ln in lines:
362             actor = getActor(ln)
363             if actor is not None:
364                 renderer.RemoveActor(actor)
365                 pass
366             pass
367         __data_model__.removeObjects(lines)
368         sg.updateObjBrowser()
369         pass
370     pass
371
372 # Remove all lines from all paragraphs
373 def clearAll():
374     global __data_model__
375     paragraphs = __data_model__.getParagraphs()
376     for paragr in paragraphs:
377         lines = sgPyQt.getChildren(paragr)
378         __data_model__.removeObjects(lines)
379         renderer=libSalomePy.getRenderer()
380         for l in lines:
381             actor = getActor(l)
382             if actor is not None:
383                 renderer.RemoveActor(actor)
384                 pass
385             pass
386     sg.updateObjBrowser()
387     pass
388
389 # Display the selected line
390 def displayLine():
391     global __data_model__
392     if sg.SelectedCount() != 1:
393         return
394     entry = sg.getSelected(0)
395     obj = ctx.DM.getObject(entry)
396     if obj is None:
397         QMessageBox.information(sgPyQt.getDesktop(),
398                                 'Info',
399                                 'Please, select line!')
400         return
401     text = obj.getText()
402     if text == "\n":
403         return
404     renderer=libSalomePy.getRenderer()
405     actor = getActor(entry)
406     if actor is None:
407         actor = vtk.vtkTextActor()
408         dict_actors[entry] = actor
409         pass
410     center = renderer.GetCenter()
411     actor.SetInput(str(text))
412     actor.SetPosition(center[0],center[1])
413     txtPr = vtk.vtkTextProperty()
414     txtPr.SetFontSize(30)
415     actor.SetTextProperty(txtPr)
416     for act in  list(dict_actors.values()):
417         renderer.RemoveActor(act)
418     renderer.AddActor(actor)
419     pass
420
421 # Clear remove all lines under selected paragraph
422 def clearParagraph():
423     global __data_model__
424     lines = sgPyQt.getChildren(sg.getSelected(0))
425     __data_model__.removeObjects(lines)
426     sg.updateObjBrowser()
427     pass
428
429 # Erase the selected line
430 def eraseLine():
431     global __data_model__
432     if sg.SelectedCount() != 1:
433         return
434     entry = sg.getSelected(0)
435     obj = __data_model__.getObject(entry)
436     if obj is None:
437         QMessageBox.information(sgPyQt.getDesktop(),
438                                 'Info',
439                                 'Please, select line!')
440         return
441     text = obj.getText()
442     if text == "\n":
443         return
444     renderer=libSalomePy.getRenderer()
445     actor = getActor(entry)
446     if actor is not None:
447         renderer.RemoveActor(actor)
448         pass
449     pass
450
451 # Return vtkActor by entry
452 def getActor(entry):
453     entry = str(entry)
454     if entry in dict_actors:
455         return dict_actors[entry]
456     return None
457
458 # Define commands
459 dict_command = {
460     951 : loadfile,
461     952 : savefile,
462     961 : insertLine,
463     962 : editLine,
464     963 : removeLine,
465     964 : clearAll,
466     971 : displayLine,
467     972 : eraseLine,
468     973 : clearParagraph,
469     }
470
471 # Define actions
472 dict_actions = {
473     "loadfile"   :    951,
474     "savefile"   :    952,
475     "insertLine" :    961,
476     "editLine"   :    962,
477     "removeLine" :    963,
478     "clearAll"   :    964,
479     "displayLine":    971,
480     "eraseLine"  :    972,
481     "clearParagraph": 973,
482     }
483
484 # Define Actors
485 dict_actors = {}