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)
31 from omniORB import CORBA
32 from SALOME_NamingServicePy import *
33 from LifeCycleCORBA import *
35 import SALOMEDS_Attributes_idl
39 ################################################
41 # Used to store actions, menus, toolbars, etc...
42 ################################################
46 MODULE_NAME = "PYHELLO"
48 MODULE_PIXMAP = "PYHELLO.png"
53 # menus/toolbars/actions IDs
56 CREATE_OBJECT_ID = 942
67 DEFAULT_NAME = "Object"
71 # create top-level menu
72 mid = sgPyQt.createMenu( "PyHello", -1, GUIcontext.PYHELLO_MENU_ID, sgPyQt.defaultMenuGroup() )
74 tid = sgPyQt.createTool( "PyHello" )
75 # create actions and fill menu and toolbar with actions
76 a = sgPyQt.createAction( GUIcontext.HELLO_ID, "Hello", "Hello", "Show hello dialog box", "ExecPYHELLO.png" )
77 sgPyQt.createMenu( a, mid )
78 sgPyQt.createTool( a, tid )
79 a = sgPyQt.createSeparator()
80 sgPyQt.createMenu( a, mid )
81 a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
82 sgPyQt.createMenu( a, mid )
83 a = sgPyQt.createSeparator()
84 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.setToggleAction( True )
91 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
92 a.setToggleAction( True )
94 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
95 a.setToggleAction( 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 ).setOn( True )
101 # the following action are used in context popup
102 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
103 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
104 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
105 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
109 ################################################
111 ################################################
113 # study-to-context map
114 __study2context__ = {}
116 __current_context__ = None
120 ################################################
122 # Get SALOME PyQt interface
124 sgPyQt = SalomePyQt.SalomePyQt()
126 # Get SALOME Swig interface
127 import libSALOME_Swig
128 sg = libSALOME_Swig.SALOMEGUI_Swig()
130 ################################################
133 orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
135 # create naming service instance
136 naming_service = SALOME_NamingServicePy_i( orb )
138 # create life cycle CORBA instance
139 lcc = LifeCycleCORBA( orb )
142 obj = naming_service.Resolve( '/myStudyManager' )
143 studyManager = obj._narrow( SALOMEDS.StudyManager )
145 ################################################
147 ################################################
155 if __verbose__ is None:
157 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
168 engine = lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
172 # get active study ID
175 return sgPyQt.getStudyId()
181 studyId = _getStudyId()
182 study = studyManager.GetStudyByID( studyId )
186 # returns True if object has children
188 def _hasChildren( sobj ):
191 iter = study.NewChildIterator( sobj )
193 name = iter.Value().GetName()
202 # finds or creates component object
204 def _findOrCreateComponent():
206 father = study.FindComponent( GUIcontext.MODULE_NAME )
208 builder = study.NewBuilder()
209 father = builder.NewComponent( GUIcontext.MODULE_NAME )
210 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
211 attr.SetValue( GUIcontext.MODULE_NAME )
212 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
213 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
214 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
215 attr.SetValue( GUIcontext.MODULE_ID )
217 builder.DefineComponentInstance( father, _getEngine() )
225 # get current GUI context
228 global __current_context__
229 return __current_context__
232 # set and return current GUI context
233 # study ID is passed as parameter
235 def _setContext( studyID ):
236 global __study2context__, __current_context__
237 if not __study2context__.has_key(studyID):
238 __study2context__[studyID] = GUIcontext()
240 __current_context__ = __study2context__[studyID]
241 return __current_context__
244 # increment object counter in the map
246 def _incObjToMap( m, id ):
247 if id not in m: m[id] = 0
255 selcount = sg.SelectedCount()
258 for i in range( selcount ):
259 entry = sg.getSelected( i )
261 sobj = study.FindObjectID( entry )
263 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
265 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
267 _incObjToMap( seltypes, ID )
272 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
274 return selcount, seltypes
276 ################################################
278 ################################################
280 # called when module is initialized
281 # perform initialization actions
283 if verbose() : print "PYHELLOGUI.initialize() : study : %d" % _getStudyId()
284 # set default preferences values
285 if not sgPyQt.hasSetting( "PYHELLO", "def_obj_name"):
286 sgPyQt.addSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME )
287 if not sgPyQt.hasSetting( "PYHELLO", "creation_mode"):
288 sgPyQt.addSetting( "PYHELLO", "creation_mode", 0 )
291 # called when module is initialized
292 # return map of popup windows to be used by the module
294 if verbose() : print "PYHELLOGUI.windows() : study : %d" % _getStudyId()
296 wm[SalomePyQt.WT_ObjectBrowser] = Qt.DockLeft
297 wm[SalomePyQt.WT_PyConsole] = Qt.DockBottom
300 # called when module is initialized
301 # return list of 2d/3d views to be used ny the module
303 if verbose() : print "PYHELLOGUI.views() : study : %d" % _getStudyId()
306 # called when module is initialized
307 # export module's preferences
308 def createPreferences():
309 if verbose() : print "PYHELLOGUI.createPreferences() : study : %d" % _getStudyId()
310 gid = sgPyQt.addPreference( "General" )
311 gid = sgPyQt.addPreference( "Object creation", gid )
312 pid = sgPyQt.addPreference( "Default name", gid, SalomePyQt.PT_String, "PYHELLO", "def_obj_name" )
313 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "PYHELLO", "creation_mode" )
314 sgPyQt.addPreferenceProperty( pid, "strings", 0, QVariant( "Default name" ) )
315 sgPyQt.addPreferenceProperty( pid, "indexes", 0, QVariant( 0 ) )
316 sgPyQt.addPreferenceProperty( pid, "strings", 1, QVariant( "Generate name" ) )
317 sgPyQt.addPreferenceProperty( pid, "indexes", 1, QVariant( 1 ) )
318 sgPyQt.addPreferenceProperty( pid, "strings", 2, QVariant( "Ask name" ) )
319 sgPyQt.addPreferenceProperty( pid, "indexes", 2, QVariant( 2 ) )
322 # called when module is activated
323 # returns True if activating is successfull and False otherwise
325 if verbose() : print "PYHELLOGUI.activate() : study : %d" % _getStudyId()
326 ctx = _setContext( _getStudyId() )
329 # called when module is deactivated
331 if verbose() : print "PYHELLOGUI.deactivate() : study : %d" % _getStudyId()
334 # called when active study is changed
335 # active study ID is passed as parameter
336 def activeStudyChanged( studyID ):
337 if verbose() : print "PYHELLOGUI.activeStudyChanged(): study : %d" % studyID
338 ctx = _setContext( _getStudyId() )
341 # called when popup menu is invoked
342 # popup menu and menu context are passed as parameters
343 def createPopupMenu( popup, context ):
344 if verbose() : print "PYHELLOGUI.createPopupMenu(): context = %s" % context
345 ctx = _setContext( _getStudyId() )
347 selcount, selected = _getSelection()
348 print selcount, selected
350 # one object is selected
351 if GUIcontext.MODULE_ID in selected:
353 sgPyQt.action( GUIcontext.DELETE_ALL_ID ).addTo( popup )
354 elif GUIcontext.OBJECT_ID in selected:
356 sgPyQt.action( GUIcontext.SHOW_ME_ID ).addTo( popup )
357 sgPyQt.action( GUIcontext.RENAME_ME_ID ).addTo( popup )
358 popup.insertSeparator()
359 sgPyQt.action( GUIcontext.DELETE_ME_ID ).addTo( popup )
363 # several objects are selected
364 if len( selected ) == 1:
365 if GUIcontext.MODULE_ID in selected:
367 sgPyQt.action( GUIcontext.DELETE_ALL_ID ).addTo( popup )
368 elif GUIcontext.OBJECT_ID in selected:
369 # menu for list of objects
370 sgPyQt.action( GUIcontext.DELETE_ME_ID ).addTo( popup )
376 # called when GUI action is activated
377 # action ID is passed as parameter
378 def OnGUIEvent( commandID ):
379 if verbose() : print "PYHELLOGUI.OnGUIEvent(): command = %d" % commandID
380 if dict_command.has_key( commandID ):
382 dict_command[commandID]()
384 traceback.print_exc()
386 if verbose() : print "The command is not implemented: %d" % commandID
389 # called when module's preferences are changed
390 # preference's resources section and setting name are passed as parameters
391 def preferenceChanged( section, setting ):
392 if verbose() : print "PYHELLOGUI.preferenceChanged(): %s / %s" % ( section, setting )
395 # called when active view is changed
396 # view ID is passed as parameter
397 def activeViewChanged( viewID ):
398 if verbose() : print "PYHELLOGUI.activeViewChanged(): %d" % viewID
401 # called when active view is cloned
402 # cloned view ID is passed as parameter
403 def viewCloned( viewID ):
404 if verbose() : print "PYHELLOGUI.viewCloned(): %d" % viewID
407 # called when active view is viewClosed
408 # view ID is passed as parameter
409 def viewClosed( viewID ):
410 if verbose() : print "PYHELLOGUI.viewClosed(): %d" % viewID
413 # called when study is opened
416 if verbose() : print "PYHELLOGUI.engineIOR()"
417 return orb.object_to_string(_getEngine())
419 ################################################
420 # GUI actions implementation
421 ################################################
426 class MyDialog( QDialog ):
428 def __init__( self, parent = None, modal = 0):
429 QDialog.__init__( self, parent, "MyDialog", modal )
430 self.setCaption( "HELLO!" )
431 vb = QVBoxLayout( self, 8 )
434 label = QLabel( "Prenom: ", hb0 )
435 self.entry = QLineEdit( hb0 )
436 self.entry.setMinimumWidth( 200 )
439 bOk = QPushButton( "&OK", hb1 )
440 self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
441 dummy = QWidget( hb1 )
442 bCancel = QPushButton( "&Cancel", hb1 )
443 self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
444 hb1.setStretchFactor( dummy, 10 )
449 name = str( self.entry.text() )
451 banner = _getEngine().makeBanner( name )
452 QMessageBox.information( self, 'Info', banner )
455 QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
459 # Show 'HELLO' dialog box
463 d = MyDialog( sgPyQt.getDesktop(), 1 )
472 default_name = str( sgPyQt.stringSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME ).stripWhiteSpace() )
473 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isOn():
474 # request object name from the user
475 name, ok = QInputDialog.getText( "Create Object", "Enter object name:", QLineEdit.Normal, default_name )
477 name = str( name.stripWhiteSpace() )
478 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isOn():
479 # generate object name
482 name = "%s %d" % ( default_name, __id__ )
488 builder = study.NewBuilder()
489 father = _findOrCreateComponent()
490 object = builder.NewObject( father )
491 attr = builder.FindOrCreateAttribute( object, "AttributeName" )
492 attr.SetValue( name )
493 attr = builder.FindOrCreateAttribute( object, "AttributeLocalID" )
494 attr.SetValue( GUIcontext.OBJECT_ID )
495 sg.updateObjBrowser( True )
503 father = study.FindComponent( GUIcontext.MODULE_NAME )
505 iter = study.NewChildIterator( father )
506 builder = study.NewBuilder()
510 builder.RemoveObjectWithChildren( sobj )
512 sg.updateObjBrowser(True)
521 entry = sg.getSelected( 0 )
523 sobj = study.FindObjectID( entry )
525 test, attr = sobj.FindAttribute( "AttributeName" )
527 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
534 # Delete selected object(s)
538 builder = study.NewBuilder()
539 if sg.SelectedCount() <= 0: return
540 for i in range( sg.SelectedCount() ):
541 entry = sg.getSelected( i )
543 sobj = study.FindObjectID( entry )
545 builder.RemoveObject( sobj )
549 sg.updateObjBrowser( True )
553 # Rename selected object
557 builder = study.NewBuilder()
558 entry = sg.getSelected( 0 )
560 sobj = study.FindObjectID( entry )
562 name, ok = QInputDialog.getText( "Object name", "Enter object name:", QLineEdit.Normal, sobj.GetName() )
563 name = str( name.stripWhiteSpace() )
564 if not ok or not name: return
565 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
566 attr.SetValue( name )
567 sg.updateObjBrowser( True )
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,