1 # Copyright (C) 2007-2008 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.
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
23 # File : PYHELLOGUI.py
24 # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
29 from PyQt4.QtGui import *
30 from PyQt4.QtCore import *
32 from omniORB import CORBA
33 from SALOME_NamingServicePy import *
34 from LifeCycleCORBA import *
36 import SALOMEDS_Attributes_idl
40 ################################################
42 # Used to store actions, menus, toolbars, etc...
43 ################################################
47 MODULE_NAME = "PYHELLO"
49 MODULE_PIXMAP = "PYHELLO_small.png"
54 # menus/toolbars/actions IDs
57 CREATE_OBJECT_ID = 942
68 DEFAULT_NAME = "Object"
72 # create top-level menu
73 mid = sgPyQt.createMenu( "PyHello", -1, GUIcontext.PYHELLO_MENU_ID, sgPyQt.defaultMenuGroup() )
75 tid = sgPyQt.createTool( "PyHello" )
76 # create actions and fill menu and toolbar with actions
77 a = sgPyQt.createAction( GUIcontext.HELLO_ID, "Hello", "Hello", "Show hello dialog box", "ExecPYHELLO.png" )
78 sgPyQt.createMenu( a, mid )
79 sgPyQt.createTool( a, tid )
80 a = sgPyQt.createSeparator()
81 sgPyQt.createMenu( a, mid )
82 a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
83 sgPyQt.createMenu( a, mid )
84 a = sgPyQt.createSeparator()
85 sgPyQt.createMenu( a, mid )
87 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
88 ag.setText( "Creation mode" )
89 ag.setUsesDropDown(True)
90 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
91 a.setCheckable( True )
93 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
94 a.setCheckable( True )
96 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
97 a.setCheckable( True )
99 sgPyQt.createMenu( ag, mid )
100 sgPyQt.createTool( ag, tid )
101 default_mode = sgPyQt.integerSetting( "PYHELLO", "creation_mode", 0 )
102 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
105 # the following action are used in context popup
106 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
107 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
108 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
109 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
113 ################################################
115 ################################################
117 # study-to-context map
118 __study2context__ = {}
120 __current_context__ = None
124 ################################################
126 # Get SALOME PyQt interface
128 sgPyQt = SalomePyQt.SalomePyQt()
130 # Get SALOME Swig interface
131 import libSALOME_Swig
132 sg = libSALOME_Swig.SALOMEGUI_Swig()
134 ################################################
137 orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
139 # create naming service instance
140 naming_service = SALOME_NamingServicePy_i( orb )
142 # create life cycle CORBA instance
143 lcc = LifeCycleCORBA( orb )
146 obj = naming_service.Resolve( '/myStudyManager' )
147 studyManager = obj._narrow( SALOMEDS.StudyManager )
149 ################################################
151 ################################################
159 if __verbose__ is None:
161 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
172 engine = lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
176 # get active study ID
179 return sgPyQt.getStudyId()
185 studyId = _getStudyId()
186 study = studyManager.GetStudyByID( studyId )
190 # returns True if object has children
192 def _hasChildren( sobj ):
195 iter = study.NewChildIterator( sobj )
197 name = iter.Value().GetName()
206 # finds or creates component object
208 def _findOrCreateComponent():
210 father = study.FindComponent( GUIcontext.MODULE_NAME )
212 builder = study.NewBuilder()
213 father = builder.NewComponent( GUIcontext.MODULE_NAME )
214 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
215 attr.SetValue( GUIcontext.MODULE_NAME )
216 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
217 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
218 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
219 attr.SetValue( GUIcontext.MODULE_ID )
221 builder.DefineComponentInstance( father, _getEngine() )
229 # get current GUI context
232 global __current_context__
233 return __current_context__
236 # set and return current GUI context
237 # study ID is passed as parameter
239 def _setContext( studyID ):
240 global __study2context__, __current_context__
241 if not __study2context__.has_key(studyID):
242 __study2context__[studyID] = GUIcontext()
244 __current_context__ = __study2context__[studyID]
245 return __current_context__
248 # increment object counter in the map
250 def _incObjToMap( m, id ):
251 if id not in m: m[id] = 0
259 selcount = sg.SelectedCount()
262 for i in range( selcount ):
263 entry = sg.getSelected( i )
265 sobj = study.FindObjectID( entry )
267 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
269 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
271 _incObjToMap( seltypes, ID )
276 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
278 return selcount, seltypes
280 ################################################
282 ################################################
284 # called when module is initialized
285 # perform initialization actions
287 if verbose() : print "PYHELLOGUI.initialize() : study : %d" % _getStudyId()
288 # set default preferences values
289 if not sgPyQt.hasSetting( "PYHELLO", "def_obj_name"):
290 sgPyQt.addSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME )
291 if not sgPyQt.hasSetting( "PYHELLO", "creation_mode"):
292 sgPyQt.addSetting( "PYHELLO", "creation_mode", 0 )
295 # called when module is initialized
296 # return map of popup windows to be used by the module
298 if verbose() : print "PYHELLOGUI.windows() : study : %d" % _getStudyId()
300 wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
301 wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
304 # called when module is initialized
305 # return list of 2d/3d views to be used ny the module
307 if verbose() : print "PYHELLOGUI.views() : study : %d" % _getStudyId()
310 # called when module is initialized
311 # export module's preferences
312 def createPreferences():
313 if verbose() : print "PYHELLOGUI.createPreferences() : study : %d" % _getStudyId()
314 gid = sgPyQt.addPreference( "General" )
315 gid = sgPyQt.addPreference( "Object creation", gid )
316 pid = sgPyQt.addPreference( "Default name", gid, SalomePyQt.PT_String, "PYHELLO", "def_obj_name" )
317 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "PYHELLO", "creation_mode" )
318 strings = QStringList()
319 strings.append( "Default name" )
320 strings.append( "Generate name" )
321 strings.append( "Ask name" )
323 indexes.append( QVariant(0) )
324 indexes.append( QVariant(1) )
325 indexes.append( QVariant(2) )
326 sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
327 sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
330 # called when module is activated
331 # returns True if activating is successfull and False otherwise
333 if verbose() : print "PYHELLOGUI.activate() : study : %d" % _getStudyId()
334 ctx = _setContext( _getStudyId() )
337 # called when module is deactivated
339 if verbose() : print "PYHELLOGUI.deactivate() : study : %d" % _getStudyId()
342 # called when active study is changed
343 # active study ID is passed as parameter
344 def activeStudyChanged( studyID ):
345 if verbose() : print "PYHELLOGUI.activeStudyChanged(): study : %d" % studyID
346 ctx = _setContext( _getStudyId() )
349 # called when popup menu is invoked
350 # popup menu and menu context are passed as parameters
351 def createPopupMenu( popup, context ):
352 if verbose() : print "PYHELLOGUI.createPopupMenu(): context = %s" % context
353 ctx = _setContext( _getStudyId() )
355 selcount, selected = _getSelection()
356 print selcount, selected
358 # one object is selected
359 if GUIcontext.MODULE_ID in selected:
361 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
362 elif GUIcontext.OBJECT_ID in selected:
364 popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
365 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
367 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
371 # several objects are selected
372 if len( selected ) == 1:
373 if GUIcontext.MODULE_ID in selected:
375 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
376 elif GUIcontext.OBJECT_ID in selected:
377 # menu for list of objects
378 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
384 # called when GUI action is activated
385 # action ID is passed as parameter
386 def OnGUIEvent( commandID ):
387 if verbose() : print "PYHELLOGUI.OnGUIEvent(): command = %d" % commandID
388 if dict_command.has_key( commandID ):
390 dict_command[commandID]()
392 traceback.print_exc()
394 if verbose() : print "The command is not implemented: %d" % commandID
397 # called when module's preferences are changed
398 # preference's resources section and setting name are passed as parameters
399 def preferenceChanged( section, setting ):
400 if verbose() : print "PYHELLOGUI.preferenceChanged(): %s / %s" % ( section, setting )
403 # called when active view is changed
404 # view ID is passed as parameter
405 def activeViewChanged( viewID ):
406 if verbose() : print "PYHELLOGUI.activeViewChanged(): %d" % viewID
409 # called when active view is cloned
410 # cloned view ID is passed as parameter
411 def viewCloned( viewID ):
412 if verbose() : print "PYHELLOGUI.viewCloned(): %d" % viewID
415 # called when active view is viewClosed
416 # view ID is passed as parameter
417 def viewClosed( viewID ):
418 if verbose() : print "PYHELLOGUI.viewClosed(): %d" % viewID
421 ################################################
422 # GUI actions implementation
423 ################################################
428 class MyDialog( QDialog ):
430 def __init__( self, parent = None, modal = 0):
431 QDialog.__init__( self, parent )
432 self.setObjectName( "MyDialog" )
433 self.setModal( modal )
434 self.setWindowTitle( "HELLO!" )
435 vb = QVBoxLayout( self )
438 hb0 = QHBoxLayout( self )
439 label = QLabel( "Prenom: ", self )
440 hb0.addWidget( label )
441 self.entry = QLineEdit( self )
442 self.entry.setMinimumWidth( 200 )
443 hb0.addWidget( self.entry )
446 hb1 = QHBoxLayout( self )
447 bOk = QPushButton( "&OK", self )
448 self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
453 bCancel = QPushButton( "&Cancel", self )
454 self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
455 hb1.addWidget( bCancel )
462 name = str( self.entry.text() )
464 banner = _getEngine().makeBanner( name )
465 QMessageBox.information( self, 'Info', banner )
468 QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
472 # Show 'HELLO' dialog box
476 d = MyDialog( sgPyQt.getDesktop(), 1 )
485 default_name = str( sgPyQt.stringSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME ).trimmed() )
487 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
488 # request object name from the user
489 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
491 "Enter object name:",
495 name = str( name.trimmed() )
496 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
497 # generate object name
500 name = "%s %d" % ( default_name, __id__ )
506 # generate object name
509 name = "%s %d" % ( default_name, __id__ )
513 builder = study.NewBuilder()
514 father = _findOrCreateComponent()
515 object = builder.NewObject( father )
516 attr = builder.FindOrCreateAttribute( object, "AttributeName" )
517 attr.SetValue( name )
518 attr = builder.FindOrCreateAttribute( object, "AttributeLocalID" )
519 attr.SetValue( GUIcontext.OBJECT_ID )
520 sg.updateObjBrowser( True )
528 father = study.FindComponent( GUIcontext.MODULE_NAME )
530 iter = study.NewChildIterator( father )
531 builder = study.NewBuilder()
535 builder.RemoveObjectWithChildren( sobj )
537 sg.updateObjBrowser( True )
546 entry = sg.getSelected( 0 )
548 sobj = study.FindObjectID( entry )
550 test, attr = sobj.FindAttribute( "AttributeName" )
552 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
559 # Delete selected object(s)
563 builder = study.NewBuilder()
564 if sg.SelectedCount() <= 0: return
565 for i in range( sg.SelectedCount() ):
566 entry = sg.getSelected( i )
568 sobj = study.FindObjectID( entry )
570 builder.RemoveObject( sobj )
574 sg.updateObjBrowser( True )
578 # Rename selected object
582 builder = study.NewBuilder()
583 entry = sg.getSelected( 0 )
585 sobj = study.FindObjectID( entry )
587 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
589 "Enter object name:",
592 name = str( name.trimmed() )
593 if not ok or not name: return
594 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
595 attr.SetValue( name )
596 sg.updateObjBrowser( True )
602 # Commands dictionary
605 GUIcontext.HELLO_ID : ShowHELLO,
606 GUIcontext.CREATE_OBJECT_ID : CreateObject,
607 GUIcontext.DELETE_ALL_ID : DeleteAll,
608 GUIcontext.SHOW_ME_ID : ShowMe,
609 GUIcontext.DELETE_ME_ID : Delete,
610 GUIcontext.RENAME_ME_ID : Rename,