1 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 # File : PYHELLOGUI.py
25 # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
30 from PYHELLO_utils import (moduleName, getStudyManager, getObjectID, verbose,
31 moduleID, objectID, getEngineIOR, getEngine)
32 from SalomePyQt import (SalomePyQt, WT_ObjectBrowser, WT_PyConsole, PT_Selector, # @UnresolvedImport
33 PT_String) # @UnresolvedImport
34 from qtsalome import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, # @UnresolvedImport
35 QPushButton, QMessageBox, QInputDialog, Qt) # @UnresolvedImport
36 from salome.kernel import termcolor
37 from salome.kernel.logger import Logger
41 logger = Logger(moduleName(), color=termcolor.RED_FG)
43 ################################################
45 # Used to store actions, menus, toolbars, etc...
46 ################################################
49 # menus/toolbars/actions IDs
52 CREATE_OBJECT_ID = 942
64 DEFAULT_NAME = "Object"
66 DEFAULT_PASSWD = "Passwd"
70 # create top-level menu
71 mid = sgPyQt.createMenu( "PyHello", -1, GUIcontext.PYHELLO_MENU_ID, sgPyQt.defaultMenuGroup() )
73 tid = sgPyQt.createTool( "PyHello" )
74 # create actions and fill menu and toolbar with actions
75 a = sgPyQt.createAction( GUIcontext.HELLO_ID, "Hello", "Hello", "Show hello dialog box", "ExecPYHELLO.png" )
76 sgPyQt.createMenu( a, mid )
77 sgPyQt.createTool( a, tid )
78 a = sgPyQt.createSeparator()
79 sgPyQt.createMenu( a, mid )
80 a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
81 sgPyQt.createMenu( a, mid )
82 a = sgPyQt.createSeparator()
83 sgPyQt.createMenu( a, mid )
85 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
86 ag.setText( "Creation mode" )
87 ag.setUsesDropDown(True)
88 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
89 a.setCheckable( True )
91 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
92 a.setCheckable( True )
94 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
95 a.setCheckable( True )
97 sgPyQt.createMenu( ag, mid )
98 sgPyQt.createTool( ag, tid )
99 default_mode = sgPyQt.integerSetting( "PYHELLO", "creation_mode", 0 )
100 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
103 a = sgPyQt.createSeparator()
104 a = sgPyQt.createAction( GUIcontext.PASSWORD_ID, "Display password", "Display password", "Display password" )
105 sgPyQt.createMenu( a, mid )
107 # the following action are used in context popup
108 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
109 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
110 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
111 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
115 ################################################
117 ################################################
119 # study-to-context map
120 __study2context__ = {}
122 __current_context__ = None
126 ################################################
128 # Get SALOME PyQt interface
129 sgPyQt = SalomePyQt()
131 # Get SALOME Swig interface
132 sg = libSALOME_Swig.SALOMEGUI_Swig()
134 ################################################
136 ################################################
138 ################################################
141 # get active study ID
144 return sgPyQt.getStudyId()
150 studyId = _getStudyId()
151 study = getStudyManager().GetStudyByID( studyId )
155 # returns True if object has children
157 def _hasChildren( sobj ):
160 iter = study.NewChildIterator( sobj )
162 name = iter.Value().GetName()
171 # get current GUI context
174 global __current_context__
175 return __current_context__
178 # set and return current GUI context
179 # study ID is passed as parameter
181 def _setContext( studyID ):
182 global __study2context__, __current_context__
183 if studyID not in __study2context__:
184 __study2context__[studyID] = GUIcontext()
186 __current_context__ = __study2context__[studyID]
187 return __current_context__
190 # increment object counter in the map
192 def _incObjToMap( m, id ):
193 if id not in m: m[id] = 0
201 selcount = sg.SelectedCount()
203 for i in range( selcount ):
204 _incObjToMap( seltypes, getObjectID( _getStudy(), sg.getSelected( i ) ) )
206 return selcount, seltypes
208 ################################################
210 ################################################
212 # called when module is initialized
213 # perform initialization actions
215 if verbose() : print("PYHELLOGUI.initialize() : study : %d" % _getStudyId())
216 # set default preferences values
217 if not sgPyQt.hasSetting( "PYHELLO", "def_obj_name"):
218 sgPyQt.addSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME )
219 if not sgPyQt.hasSetting( "PYHELLO", "creation_mode"):
220 sgPyQt.addSetting( "PYHELLO", "creation_mode", 0 )
221 if not sgPyQt.hasSetting( "PYHELLO", "Password"):
222 sgPyQt.addSetting( "PYHELLO", "Password", GUIcontext.DEFAULT_PASSWD )
225 # called when module is initialized
226 # return map of popup windows to be used by the module
228 if verbose() : print("PYHELLOGUI.windows() : study : %d" % _getStudyId())
230 wm[WT_ObjectBrowser] = Qt.LeftDockWidgetArea
231 wm[WT_PyConsole] = Qt.BottomDockWidgetArea
234 # called when module is initialized
235 # return list of 2d/3d views to be used ny the module
237 if verbose() : print("PYHELLOGUI.views() : study : %d" % _getStudyId())
240 # called when module is initialized
241 # export module's preferences
242 def createPreferences():
244 print("PYHELLOGUI.createPreferences() : study : %d" % _getStudyId())
245 gid = sgPyQt.addPreference("General")
246 gid = sgPyQt.addPreference("Object creation", gid)
247 sgPyQt.addPreference("Default name", gid, PT_String, "PYHELLO", "def_obj_name")
248 pid = sgPyQt.addPreference("Default creation mode", gid, PT_Selector, "PYHELLO", "creation_mode")
249 strings = ["Default name", "Generate name", "Ask name"]
251 sgPyQt.setPreferenceProperty(pid, "strings", strings)
252 sgPyQt.setPreferenceProperty(pid, "indexes", indexes)
253 pid = sgPyQt.addPreference("Password", gid, PT_String, "PYHELLO", "Password")
254 sgPyQt.setPreferenceProperty(pid, "echo", 2)
257 # called when module is activated
258 # returns True if activating is successfull and False otherwise
260 if verbose() : print("PYHELLOGUI.activate() : study : %d" % _getStudyId())
261 ctx = _setContext( _getStudyId() )
264 # called when module is deactivated
266 if verbose() : print("PYHELLOGUI.deactivate() : study : %d" % _getStudyId())
269 # called when active study is changed
270 # active study ID is passed as parameter
271 def activeStudyChanged( studyID ):
272 if verbose() : print("PYHELLOGUI.activeStudyChanged(): study : %d" % studyID)
273 ctx = _setContext( _getStudyId() )
276 # called when popup menu is invoked
277 # popup menu and menu context are passed as parameters
278 def createPopupMenu( popup, context ):
279 if verbose() : print("PYHELLOGUI.createPopupMenu(): context = %s" % context)
280 ctx = _setContext( _getStudyId() )
282 selcount, selected = _getSelection()
283 if verbose() : print(selcount, selected)
285 # one object is selected
286 if moduleID() in selected:
288 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
289 elif objectID() in selected:
291 popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
292 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
294 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
298 # several objects are selected
299 if len( selected ) == 1:
300 if moduleID() in selected:
302 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
303 elif objectID() in selected:
304 # menu for list of objects
305 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
311 # called when GUI action is activated
312 # action ID is passed as parameter
313 def OnGUIEvent( commandID ):
314 if verbose() : print("PYHELLOGUI.OnGUIEvent(): command = %d" % commandID)
315 if commandID in dict_command:
317 dict_command[commandID]()
319 traceback.print_exc()
321 if verbose() : print("The command is not implemented: %d" % commandID)
324 # called when module's preferences are changed
325 # preference's resources section and setting name are passed as parameters
326 def preferenceChanged( section, setting ):
327 if verbose() : print("PYHELLOGUI.preferenceChanged(): %s / %s" % ( section, setting ))
330 # called when active view is changed
331 # view ID is passed as parameter
332 def activeViewChanged( viewID ):
333 if verbose() : print("PYHELLOGUI.activeViewChanged(): %d" % viewID)
336 # called when active view is cloned
337 # cloned view ID is passed as parameter
338 def viewCloned( viewID ):
339 if verbose() : print("PYHELLOGUI.viewCloned(): %d" % viewID)
342 # called when active view is viewClosed
343 # view ID is passed as parameter
344 def viewClosed( viewID ):
345 if verbose() : print("PYHELLOGUI.viewClosed(): %d" % viewID)
348 # called when study is opened
351 if verbose() : print("PYHELLOGUI.engineIOR()")
352 return getEngineIOR()
354 # called to check if object can be dragged
355 # returns True if drag operation is allowed for this object
356 def isDraggable(what):
357 if verbose() : print("PYHELLOGUI.isDraggable()")
358 # return True if object is draggable
361 # called to check if object allows dropping on it
362 # returns True if drop operation is allowed for this object
363 def isDropAccepted(where):
364 if verbose() : print("PYHELLOGUI.isDropAccepted()")
365 # return True if object accept drops
368 # called when drag and drop operation is finished
369 # performs corresponding data re-arrangement if allowed
370 def dropObjects(what, where, row, action):
372 print("PYHELLOGUI.dropObjects()")
373 # 'what' is a list of entries of objects being dropped
374 for i in what: print("- dropped:", i)
375 # 'where' is a parent object's entry
376 print("- dropping on:", where)
377 # 'row' is an position in the parent's children list;
378 # -1 if appending to the end of children list is performed
379 print("- dropping position:", row)
380 # 'action' is a dropping action being performed:
381 # - 0x01 (Qt::CopyAction) for copy
382 # - 0x02 (Qt::MoveAction) for move
383 print("- drop action:", action)
387 ################################################
388 # GUI actions implementation
389 ################################################
394 class MyDialog( QDialog ):
396 def __init__( self, parent = None, modal = 0):
397 QDialog.__init__( self, parent )
398 self.setObjectName( "MyDialog" )
399 self.setModal( modal )
400 self.setWindowTitle( "HELLO!" )
401 vb = QVBoxLayout( self )
402 vb.setContentsMargins( 8, 8, 8, 8 )
404 hb0 = QHBoxLayout( self )
405 label = QLabel( "Prenom: ", self )
406 hb0.addWidget( label )
407 self.entry = QLineEdit( self )
408 self.entry.setMinimumWidth( 200 )
409 hb0.addWidget( self.entry )
412 hb1 = QHBoxLayout( self )
413 bOk = QPushButton( "&OK", self )
414 bOk.setIcon( sgPyQt.loadIcon( 'PYHELLO', 'ICO_HANDSHAKE' ) )
415 bOk.clicked.connect(self.accept)
420 bCancel = QPushButton( "&Cancel", self )
421 bCancel.setIcon( sgPyQt.loadIcon( 'PYHELLO', 'ICO_STOP' ) )
422 bCancel.clicked.connect(self.close)
423 hb1.addWidget( bCancel )
429 name = str( self.entry.text() )
431 banner = getEngine().makeBanner( name )
432 QMessageBox.information( self, 'Info', banner )
435 QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
439 # Show 'HELLO' dialog box
443 d = MyDialog( sgPyQt.getDesktop(), 1 )
453 default_name = sgPyQt.stringSetting("PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME).strip()
455 if sgPyQt.action(GUIcontext.OPTION_3_ID).isChecked():
456 # request object name from the user
457 name, ok = QInputDialog.getText(sgPyQt.getDesktop(),
459 "Enter object name:",
465 elif sgPyQt.action(GUIcontext.OPTION_2_ID).isChecked():
466 # generate object name
467 __objectid__ = __objectid__ + 1
468 name = "%s %d" % (default_name, __objectid__)
473 except Exception as e:
475 # generate object name
476 __objectid__ = __objectid__ + 1
477 name = "%s %d" % (default_name, __objectid__)
481 getEngine().createObject(_getStudy(), name)
482 sg.updateObjBrowser(True)
490 father = study.FindComponent( moduleName() )
492 iter = study.NewChildIterator( father )
493 builder = study.NewBuilder()
497 builder.RemoveObjectWithChildren( sobj )
499 sg.updateObjBrowser( True )
508 entry = sg.getSelected( 0 )
510 sobj = study.FindObjectID( entry )
512 test, attr = sobj.FindAttribute( "AttributeName" )
514 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
521 # Delete selected object(s)
525 builder = study.NewBuilder()
526 if sg.SelectedCount() <= 0: return
527 for i in range( sg.SelectedCount() ):
528 entry = sg.getSelected( i )
530 sobj = study.FindObjectID( entry )
532 builder.RemoveObject( sobj )
536 sg.updateObjBrowser( True )
540 # Rename selected object
544 builder = study.NewBuilder()
545 entry = sg.getSelected( 0 )
547 sobj = study.FindObjectID( entry )
549 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
551 "Enter object name:",
554 name = str( name ).strip()
555 if not ok or not name: return
556 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
557 attr.SetValue( name )
558 sg.updateObjBrowser( True )
564 # Display password stored in the preferences
567 passwd = str( sgPyQt.stringSetting( "PYHELLO", "Password", GUIcontext.DEFAULT_PASSWD ) ).strip()
568 QMessageBox.information(sgPyQt.getDesktop(),
573 # Commands dictionary
576 GUIcontext.HELLO_ID : ShowHELLO,
577 GUIcontext.CREATE_OBJECT_ID : CreateObject,
578 GUIcontext.DELETE_ALL_ID : DeleteAll,
579 GUIcontext.SHOW_ME_ID : ShowMe,
580 GUIcontext.DELETE_ME_ID : Delete,
581 GUIcontext.RENAME_ME_ID : Rename,
582 GUIcontext.PASSWORD_ID : Password,