1 # Copyright (C) 2009-2010 EDF R&D
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.
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.
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
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 from PyQt4.QtGui import *
23 from PyQt4.QtCore import *
25 from omniORB import CORBA
26 from SALOME_NamingServicePy import *
27 from LifeCycleCORBA import *
29 import SALOMEDS_Attributes_idl
31 import GENERICSOLVER_ORB
33 ################################################
35 # Used to store actions, menus, toolbars, etc...
36 ################################################
40 MODULE_NAME = "GENERICSOLVER"
42 MODULE_PIXMAP = "GENERICSOLVER_small.png"
49 # menus/toolbars/actions IDs
50 GENERICSOLVER_MENU_ID = 90
52 CREATE_OBJECT_ID = 942
57 GENERICSOLVER_TB_ID = 90
65 DEFAULT_NAME = "Object"
66 DEFAULT_CASE_NAME = "Case"
70 # create top-level menu
71 mid = sgPyQt.createMenu( "Genericsolver", -1, GUIcontext.GENERICSOLVER_MENU_ID, sgPyQt.defaultMenuGroup() )
73 tid = sgPyQt.createTool( "Genericsolver" )
74 # create actions and fill menu and toolbar with actions
75 a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create a new case", "CaseGENERICSOLVER.png" )
76 sgPyQt.createMenu( a, mid )
77 sgPyQt.createTool( a, tid )
78 a = sgPyQt.createAction( GUIcontext.SOLVER_ID, "Run Solver", "Run Solver", "Run Solver on selected case", "ExecGENERICSOLVER.png" )
79 sgPyQt.createMenu( a, mid )
80 sgPyQt.createTool( a, tid )
81 a = sgPyQt.createSeparator()
82 sgPyQt.createMenu( a, mid )
83 #a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
84 #sgPyQt.createMenu( a, mid )
85 #a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create case" )
86 #sgPyQt.createMenu( a, mid )
87 a = sgPyQt.createSeparator()
88 sgPyQt.createMenu( a, mid )
90 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
91 ag.setText( "Creation mode" )
92 ag.setUsesDropDown(True)
93 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
94 a.setCheckable( True )
96 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
97 a.setCheckable( True )
99 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
100 a.setCheckable( True )
102 sgPyQt.createMenu( ag, mid )
103 sgPyQt.createTool( ag, tid )
104 default_mode = sgPyQt.integerSetting( "GENERICSOLVER", "creation_mode", 0 )
105 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
108 # the following action are used in context popup
109 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
110 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
111 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
112 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
113 a = sgPyQt.createAction( GUIcontext.SET_VALUE_ID, "Set value", "Set Value", "Set a new value to variable" )
117 ################################################
119 ################################################
121 # study-to-context map
122 __study2context__ = {}
124 __current_context__ = None
129 ################################################
131 # Get SALOME PyQt interface
133 sgPyQt = SalomePyQt.SalomePyQt()
135 # Get SALOME Swig interface
136 import libSALOME_Swig
137 sg = libSALOME_Swig.SALOMEGUI_Swig()
139 ################################################
142 orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
144 # create naming service instance
145 naming_service = SALOME_NamingServicePy_i( orb )
147 # create life cycle CORBA instance
148 lcc = LifeCycleCORBA( orb )
151 obj = naming_service.Resolve( '/myStudyManager' )
152 studyManager = obj._narrow( SALOMEDS.StudyManager )
154 ################################################
156 ################################################
164 if __verbose__ is None:
166 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
174 # get GENERICSOLVER engine
177 engine = lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
181 # get active study ID
184 return sgPyQt.getStudyId()
190 studyId = getStudyId()
191 study = studyManager.GetStudyByID( studyId )
195 # returns True if object has children
197 def hasChildren( sobj ):
200 iter = study.NewChildIterator( sobj )
202 name = iter.Value().GetName()
211 # finds or creates component object
213 def findOrCreateComponent():
215 father = study.FindComponent( GUIcontext.MODULE_NAME )
217 builder = study.NewBuilder()
218 father = builder.NewComponent( GUIcontext.MODULE_NAME )
219 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
220 attr.SetValue( GUIcontext.MODULE_NAME )
221 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
222 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
223 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
224 attr.SetValue( GUIcontext.MODULE_ID )
226 builder.DefineComponentInstance( father, getEngine() )
234 # get current GUI context
237 global __current_context__
238 return __current_context__
241 # set and return current GUI context
242 # study ID is passed as parameter
244 def setContext( studyID ):
245 global __study2context__, __current_context__
246 if not __study2context__.has_key(studyID):
247 __study2context__[studyID] = GUIcontext()
249 __current_context__ = __study2context__[studyID]
250 return __current_context__
253 # increment object counter in the map
255 def _incObjToMap( m, id ):
256 if id not in m: m[id] = 0
264 selcount = sg.SelectedCount()
267 for i in range( selcount ):
268 entry = sg.getSelected( i )
270 sobj = study.FindObjectID( entry )
272 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
274 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
276 _incObjToMap( seltypes, ID )
281 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
283 return selcount, seltypes
285 ################################################
287 ################################################
289 # called when module is initialized
290 # perform initialization actions
292 if verbose() : print "GENERICSOLVERGUI.initialize() : study : %d" % getStudyId()
293 # set default preferences values
294 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_obj_name"):
295 sgPyQt.addSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME )
296 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_case_name"):
297 sgPyQt.addSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME )
298 if not sgPyQt.hasSetting( "GENERICSOLVER", "creation_mode"):
299 sgPyQt.addSetting( "GENERICSOLVER", "creation_mode", 0 )
302 # called when module is initialized
303 # return map of popup windows to be used by the module
305 if verbose() : print "GENERICSOLVERGUI.windows() : study : %d" % getStudyId()
307 wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
308 wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
311 # called when module is initialized
312 # return list of 2d/3d views to be used ny the module
314 if verbose() : print "GENERICSOLVERGUI.views() : study : %d" % getStudyId()
317 # called when module is initialized
318 # export module's preferences
319 def createPreferences():
320 if verbose() : print "GENERICSOLVERGUI.createPreferences() : study : %d" % getStudyId()
321 gid = sgPyQt.addPreference( "General" )
322 gid = sgPyQt.addPreference( "Object creation", gid )
323 pid = sgPyQt.addPreference( "Default object name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_obj_name" )
324 pid = sgPyQt.addPreference( "Default case name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_case_name" )
325 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "GENERICSOLVER", "creation_mode" )
326 strings = QStringList()
327 strings.append( "Default name" )
328 strings.append( "Generate name" )
329 strings.append( "Ask name" )
331 indexes.append( QVariant(0) )
332 indexes.append( QVariant(1) )
333 indexes.append( QVariant(2) )
334 sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
335 sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
338 # called when module is activated
339 # returns True if activating is successfull and False otherwise
341 if verbose() : print "GENERICSOLVERGUI.activate() : study : %d" % getStudyId()
342 ctx = setContext( getStudyId() )
345 # called when module is deactivated
347 if verbose() : print "GENERICSOLVERGUI.deactivate() : study : %d" % getStudyId()
350 # called when active study is changed
351 # active study ID is passed as parameter
352 def activeStudyChanged( studyID ):
353 if verbose() : print "GENERICSOLVERGUI.activeStudyChanged(): study : %d" % studyID
354 ctx = setContext( getStudyId() )
357 # called when popup menu is invoked
358 # popup menu and menu context are passed as parameters
359 def createPopupMenu( popup, context ):
360 if verbose() : print "GENERICSOLVERGUI.createPopupMenu(): context = %s" % context
361 ctx = setContext( getStudyId() )
363 selcount, selected = getSelection()
364 print selcount, selected
366 # one object is selected
367 if GUIcontext.MODULE_ID in selected:
369 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
370 ## elif GUIcontext.OBJECT_ID in selected:
372 ## popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
373 ## popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
374 ## popup.addSeparator()
375 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
376 elif GUIcontext.CASE_ID in selected:
378 popup.addAction( sgPyQt.action( GUIcontext.SOLVER_ID ) )
379 elif GUIcontext.VARIABLE_ID in selected:
381 popup.addAction( sgPyQt.action( GUIcontext.SET_VALUE_ID ) )
382 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
386 # several objects are selected
387 if len( selected ) == 1:
388 if GUIcontext.MODULE_ID in selected:
390 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
391 ## elif GUIcontext.OBJECT_ID in selected:
392 ## # menu for list of objects
393 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
399 # called when GUI action is activated
400 # action ID is passed as parameter
401 def OnGUIEvent( commandID ):
402 if verbose() : print "GENERICSOLVERGUI.OnGUIEvent(): command = %d" % commandID
403 if dict_command.has_key( commandID ):
405 dict_command[commandID]()
407 traceback.print_exc()
409 if verbose() : print "The command is not implemented: %d" % commandID
412 # called when module's preferences are changed
413 # preference's resources section and setting name are passed as parameters
414 def preferenceChanged( section, setting ):
415 if verbose() : print "GENERICSOLVERGUI.preferenceChanged(): %s / %s" % ( section, setting )
418 # called when active view is changed
419 # view ID is passed as parameter
420 def activeViewChanged( viewID ):
421 if verbose() : print "GENERICSOLVERGUI.activeViewChanged(): %d" % viewID
424 # called when active view is cloned
425 # cloned view ID is passed as parameter
426 def viewCloned( viewID ):
427 if verbose() : print "GENERICSOLVERGUI.viewCloned(): %d" % viewID
430 # called when active view is viewClosed
431 # view ID is passed as parameter
432 def viewClosed( viewID ):
433 if verbose() : print "GENERICSOLVERGUI.viewClosed(): %d" % viewID
436 ################################################
437 # GUI actions implementation
438 ################################################
441 # 'SOLVER' dialog box
443 ##class MyDialog( QDialog ):
445 ## def __init__( self, parent = None, modal = 0):
446 ## QDialog.__init__( self, parent )
447 ## self.setObjectName( "MyDialog" )
448 ## self.setModal( modal )
449 ## self.setWindowTitle( "SOLVER!" )
450 ## vb = QVBoxLayout( self )
453 ## hb0 = QHBoxLayout( self )
454 ## label = QLabel( "Prenom: ", self )
455 ## hb0.addWidget( label )
456 ## self.entry = QLineEdit( self )
457 ## self.entry.setMinimumWidth( 200 )
458 ## hb0.addWidget( self.entry )
459 ## vb.addLayout( hb0 )
461 ## hb1 = QHBoxLayout( self )
462 ## bOk = QPushButton( "&OK", self )
463 ## self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
464 ## hb1.addWidget( bOk )
466 ## hb1.addStretch( 10 )
468 ## bCancel = QPushButton( "&Cancel", self )
469 ## self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
470 ## hb1.addWidget( bCancel )
472 ## vb.addLayout( hb1 )
476 ## def accept( self ):
477 ## name = str( self.entry.text() )
479 ## inPoint = [1, 2, 3]
481 ## print "GENERICSOLVERGUI.accept (1): inPoint = ", inPoint
482 ## print "GENERICSOLVERGUI.accept (1): outPoint = ", outPoint
483 ## (ok,outPoint) = getEngine().Exec( inPoint, outPoint )
484 ## QMessageBox.information( self, 'Info', "Exec() method returned %d" % ok )
485 ## print "GENERICSOLVERGUI.accept (2): inPoint = ", inPoint
486 ## print "GENERICSOLVERGUI.accept (2): outPoint = ", outPoint
489 ## QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
495 def addObjectInStudy( builder, father, objname, objid ):
496 obj = getSubSObjectByName( father, objname )
498 obj = builder.NewObject( father )
499 attr = builder.FindOrCreateAttribute( obj, "AttributeName" )
500 attr.SetValue( objname )
501 attr = builder.FindOrCreateAttribute( obj, "AttributeLocalID" )
502 attr.SetValue( objid )
505 def setValueToVariable( builder, varobj, value ):
506 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
508 if (objid == GUIcontext.VARIABLE_ID):
509 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
510 attr.SetValue( value )
512 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
513 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
516 def getValueOfVariable( builder, varobj ):
517 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
519 if (objid == GUIcontext.VARIABLE_ID):
520 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
523 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
524 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
527 def getSubSObjectByName( sobjFather, childName ):
529 iter = study.NewChildIterator( sobjFather )
530 #builder = study.NewBuilder()
533 if sobj.GetName() == childName:
540 # Create a deterministic case
543 print "GENERICSOLVERGUI.CreateCase : enter"
544 default_case_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME ).trimmed() )
546 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
547 # request object name from the user
548 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
554 name = str( name.trimmed() )
555 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
556 # generate object name
559 name = "%s %d" % ( default_case_name, __id__ )
561 name = default_case_name
565 # generate object name
568 name = "%s %d" % ( default_case_name, __id__ )
572 builder = study.NewBuilder()
573 father = findOrCreateComponent()
574 case = addObjectInStudy( builder, father, name, GUIcontext.CASE_ID )
575 varE = addObjectInStudy( builder, case, "E", GUIcontext.VARIABLE_ID )
576 setValueToVariable( builder, varE, 210.e9 )
577 varF = addObjectInStudy( builder, case, "F", GUIcontext.VARIABLE_ID )
578 setValueToVariable( builder, varF, 1000. )
579 varL = addObjectInStudy( builder, case, "L", GUIcontext.VARIABLE_ID )
580 setValueToVariable( builder, varL, 1.5 )
581 varI = addObjectInStudy( builder, case, "I", GUIcontext.VARIABLE_ID )
582 setValueToVariable( builder, varI, 2.e-6 )
583 sg.updateObjBrowser( True )
584 print "GENERICSOLVERGUI.CreateCase : exit"
588 # Get the selected deterministic case
590 def GetSelectedCase():
591 entry = sg.getSelected( 0 )
594 sobj = study.FindObjectID( entry )
596 test, attr = sobj.FindAttribute( "AttributeLocalID" )
597 print "GENERICSOLVERGUI.GetSelectedCase : test=%d attr=%d" % (test,attr.Value())
598 if attr.Value() == GUIcontext.CASE_ID: # This is a case entry
599 if hasChildren( sobj ):
602 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no child for case"
605 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! not a case"
608 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! selected object not found in study"
611 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no selection"
615 # Retrieve data from selected case
617 def GetDataFromCase( caseEntry ):
620 case = study.FindObjectID( caseEntry )
621 builder = study.NewBuilder()
622 # Get the values of the variables and make them a list
623 for name in ("E", "F", "L", "I"):
624 var = getSubSObjectByName( case, name )
626 print "GENERICSOLVERGUI.GetDataFromCase : ERROR! no variable '%s'" % name
628 theCase.append( getValueOfVariable( builder, var ) )
632 # Add some variable to the case
634 def AddDataToCase( caseEntry, varName, varValue ):
636 case = study.FindObjectID( caseEntry )
637 builder = study.NewBuilder()
638 var = addObjectInStudy( builder, case, varName, GUIcontext.VARIABLE_ID )
639 setValueToVariable( builder, var, varValue )
640 sg.updateObjBrowser( True )
647 case = GetSelectedCase()
648 getEngine().Init( getStudyId(), case, "" )
650 inPoint = GetDataFromCase( case )[:2]
652 print "GENERICSOLVERGUI.RunSOLVER (1): inPoint = ", inPoint
653 print "GENERICSOLVERGUI.RunSOLVER (1): outPoint = ", outPoint
654 (ok,outPoint) = getEngine().Exec( inPoint, outPoint )
655 print "GENERICSOLVERGUI.RunSOLVER (2): inPoint = ", inPoint
656 print "GENERICSOLVERGUI.RunSOLVER (2): outPoint = ", outPoint
657 AddDataToCase( case, "Deviation", outPoint[0] )
659 getEngine().Finalize()
666 ##def CreateObject():
667 ## default_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME ).trimmed() )
669 ## if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
670 ## # request object name from the user
671 ## name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
673 ## "Enter object name:",
677 ## name = str( name.trimmed() )
678 ## elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
679 ## # generate object name
681 ## __id__ = __id__ + 1
682 ## name = "%s %d" % ( default_name, __id__ )
684 ## name = default_name
688 ## # generate object name
690 ## __id__ = __id__ + 1
691 ## name = "%s %d" % ( default_name, __id__ )
693 ## if not name: return
694 ## study = getStudy()
695 ## builder = study.NewBuilder()
696 ## father = findOrCreateComponent()
697 ## obj = addObjectInStudy( builder, father, name, GUIcontext.OBJECT_ID )
698 ## sg.updateObjBrowser( True )
706 father = study.FindComponent( GUIcontext.MODULE_NAME )
708 iter = study.NewChildIterator( father )
709 builder = study.NewBuilder()
713 builder.RemoveObjectWithChildren( sobj )
715 sg.updateObjBrowser( True )
724 entry = sg.getSelected( 0 )
726 sobj = study.FindObjectID( entry )
728 test, attr = sobj.FindAttribute( "AttributeName" )
730 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
737 # Delete selected object(s)
741 builder = study.NewBuilder()
742 if sg.SelectedCount() <= 0: return
743 for i in range( sg.SelectedCount() ):
744 entry = sg.getSelected( i )
746 sobj = study.FindObjectID( entry )
748 builder.RemoveObject( sobj )
752 sg.updateObjBrowser( True )
756 # Rename selected object
760 builder = study.NewBuilder()
761 entry = sg.getSelected( 0 )
763 sobj = study.FindObjectID( entry )
765 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
767 "Enter object name:",
770 name = str( name.trimmed() )
771 if not ok or not name: return
772 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
773 attr.SetValue( name )
774 sg.updateObjBrowser( True )
780 # Set value to variable
784 builder = study.NewBuilder()
785 entry = sg.getSelected( 0 )
787 sobj = study.FindObjectID( entry )
789 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
793 str(getValueOfVariable( builder, sobj)) )
794 value = float( name.trimmed() )
795 if not ok or not value: return
796 setValueToVariable( builder, sobj, value )
797 sg.updateObjBrowser( True )
803 # Commands dictionary
806 GUIcontext.SOLVER_ID : RunSOLVER,
807 GUIcontext.CREATE_CASE_ID : CreateCase,
808 ## GUIcontext.CREATE_OBJECT_ID : CreateObject,
809 GUIcontext.DELETE_ALL_ID : DeleteAll,
810 GUIcontext.SHOW_ME_ID : ShowMe,
811 GUIcontext.DELETE_ME_ID : Delete,
812 GUIcontext.RENAME_ME_ID : Rename,
813 GUIcontext.SET_VALUE_ID : SetValue,