1 # Copyright (C) 2009-2011 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
25 from PyQt4.QtGui import *
26 from PyQt4.QtCore import *
30 import GENERICSOLVER_ORB
31 from salome.kernel.parametric import study_exchange_vars
35 VARS_ICON = "icon_variables.png"
37 ################################################
39 # Used to store actions, menus, toolbars, etc...
40 ################################################
44 MODULE_NAME = "GENERICSOLVER"
46 MODULE_PIXMAP = "GENERICSOLVER_small.png"
53 # menus/toolbars/actions IDs
54 GENERICSOLVER_MENU_ID = 90
56 CREATE_OBJECT_ID = 942
61 GENERICSOLVER_TB_ID = 90
69 DEFAULT_NAME = "Object"
70 DEFAULT_CASE_NAME = "Case"
74 # create top-level menu
75 mid = sgPyQt.createMenu( "Genericsolver", -1, GUIcontext.GENERICSOLVER_MENU_ID, sgPyQt.defaultMenuGroup() )
77 tid = sgPyQt.createTool( "Genericsolver" )
78 # create actions and fill menu and toolbar with actions
79 a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create a new case", "CaseGENERICSOLVER.png" )
80 sgPyQt.createMenu( a, mid )
81 sgPyQt.createTool( a, tid )
82 a = sgPyQt.createAction( GUIcontext.SOLVER_ID, "Run Solver", "Run Solver", "Run Solver on selected case", "ExecGENERICSOLVER.png" )
83 sgPyQt.createMenu( a, mid )
84 sgPyQt.createTool( a, tid )
85 a = sgPyQt.createSeparator()
86 sgPyQt.createMenu( a, mid )
87 #a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
88 #sgPyQt.createMenu( a, mid )
89 #a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create case" )
90 #sgPyQt.createMenu( a, mid )
91 a = sgPyQt.createSeparator()
92 sgPyQt.createMenu( a, mid )
94 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
95 ag.setText( "Creation mode" )
96 ag.setUsesDropDown(True)
97 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
98 a.setCheckable( True )
100 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
101 a.setCheckable( True )
103 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
104 a.setCheckable( True )
106 sgPyQt.createMenu( ag, mid )
107 sgPyQt.createTool( ag, tid )
108 default_mode = sgPyQt.integerSetting( "GENERICSOLVER", "creation_mode", 0 )
109 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
112 # the following action are used in context popup
113 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
114 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
115 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
116 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
117 a = sgPyQt.createAction( GUIcontext.SET_VALUE_ID, "Set value", "Set Value", "Set a new value to variable" )
121 ################################################
123 ################################################
125 # study-to-context map
126 __study2context__ = {}
128 __current_context__ = None
133 ################################################
135 # Get SALOME PyQt interface
137 sgPyQt = SalomePyQt.SalomePyQt()
139 # Get SALOME Swig interface
140 import libSALOME_Swig
141 sg = libSALOME_Swig.SALOMEGUI_Swig()
143 ################################################
145 ################################################
153 if __verbose__ is None:
155 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
163 # get GENERICSOLVER engine
166 engine = salome.lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
170 # get active study ID
173 return sgPyQt.getStudyId()
179 studyId = getStudyId()
180 study = salome.myStudyManager.GetStudyByID( studyId )
184 # returns True if object has children
186 def hasChildren( sobj ):
189 iter = study.NewChildIterator( sobj )
191 name = iter.Value().GetName()
200 # finds or creates component object
202 def findOrCreateComponent():
204 father = study.FindComponent( GUIcontext.MODULE_NAME )
206 builder = study.NewBuilder()
207 father = builder.NewComponent( GUIcontext.MODULE_NAME )
208 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
209 attr.SetValue( GUIcontext.MODULE_NAME )
210 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
211 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
212 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
213 attr.SetValue( GUIcontext.MODULE_ID )
215 builder.DefineComponentInstance( father, getEngine() )
223 # get current GUI context
226 global __current_context__
227 return __current_context__
230 # set and return current GUI context
231 # study ID is passed as parameter
233 def setContext( studyID ):
234 global __study2context__, __current_context__
235 if not __study2context__.has_key(studyID):
236 __study2context__[studyID] = GUIcontext()
238 __current_context__ = __study2context__[studyID]
239 return __current_context__
242 # increment object counter in the map
244 def _incObjToMap( m, id ):
245 if id not in m: m[id] = 0
253 selcount = sg.SelectedCount()
256 for i in range( selcount ):
257 entry = sg.getSelected( i )
259 sobj = study.FindObjectID( entry )
261 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
263 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
265 _incObjToMap( seltypes, ID )
270 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
272 return selcount, seltypes
274 ################################################
276 ################################################
278 # called when module is initialized
279 # perform initialization actions
281 if verbose() : print "GENERICSOLVERGUI.initialize() : study : %d" % getStudyId()
282 # set default preferences values
283 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_obj_name"):
284 sgPyQt.addSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME )
285 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_case_name"):
286 sgPyQt.addSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME )
287 if not sgPyQt.hasSetting( "GENERICSOLVER", "creation_mode"):
288 sgPyQt.addSetting( "GENERICSOLVER", "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 "GENERICSOLVERGUI.windows() : study : %d" % getStudyId()
296 wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
297 wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
300 # called when module is initialized
301 # return list of 2d/3d views to be used ny the module
303 if verbose() : print "GENERICSOLVERGUI.views() : study : %d" % getStudyId()
306 # called when module is initialized
307 # export module's preferences
308 def createPreferences():
309 if verbose() : print "GENERICSOLVERGUI.createPreferences() : study : %d" % getStudyId()
310 gid = sgPyQt.addPreference( "General" )
311 gid = sgPyQt.addPreference( "Object creation", gid )
312 pid = sgPyQt.addPreference( "Default object name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_obj_name" )
313 pid = sgPyQt.addPreference( "Default case name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_case_name" )
314 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "GENERICSOLVER", "creation_mode" )
315 strings = QStringList()
316 strings.append( "Default name" )
317 strings.append( "Generate name" )
318 strings.append( "Ask name" )
320 indexes.append( QVariant(0) )
321 indexes.append( QVariant(1) )
322 indexes.append( QVariant(2) )
323 sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
324 sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
327 # called when module is activated
328 # returns True if activating is successfull and False otherwise
330 if verbose() : print "GENERICSOLVERGUI.activate() : study : %d" % getStudyId()
331 ctx = setContext( getStudyId() )
334 # called when module is deactivated
336 if verbose() : print "GENERICSOLVERGUI.deactivate() : study : %d" % getStudyId()
339 # called when active study is changed
340 # active study ID is passed as parameter
341 def activeStudyChanged( studyID ):
342 if verbose() : print "GENERICSOLVERGUI.activeStudyChanged(): study : %d" % studyID
343 ctx = setContext( getStudyId() )
346 # called when popup menu is invoked
347 # popup menu and menu context are passed as parameters
348 def createPopupMenu( popup, context ):
349 if verbose() : print "GENERICSOLVERGUI.createPopupMenu(): context = %s" % context
350 ctx = setContext( getStudyId() )
352 selcount, selected = getSelection()
353 print selcount, selected
355 # one object is selected
356 if GUIcontext.MODULE_ID in selected:
358 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
359 ## elif GUIcontext.OBJECT_ID in selected:
361 ## popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
362 ## popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
363 ## popup.addSeparator()
364 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
365 elif GUIcontext.CASE_ID in selected:
367 popup.addAction( sgPyQt.action( GUIcontext.SOLVER_ID ) )
368 elif GUIcontext.VARIABLE_ID in selected:
370 popup.addAction( sgPyQt.action( GUIcontext.SET_VALUE_ID ) )
371 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
375 # several objects are selected
376 if len( selected ) == 1:
377 if GUIcontext.MODULE_ID in selected:
379 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
380 ## elif GUIcontext.OBJECT_ID in selected:
381 ## # menu for list of objects
382 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
388 # called when GUI action is activated
389 # action ID is passed as parameter
390 def OnGUIEvent( commandID ):
391 if verbose() : print "GENERICSOLVERGUI.OnGUIEvent(): command = %d" % commandID
392 if dict_command.has_key( commandID ):
394 dict_command[commandID]()
396 traceback.print_exc()
398 if verbose() : print "The command is not implemented: %d" % commandID
401 # called when module's preferences are changed
402 # preference's resources section and setting name are passed as parameters
403 def preferenceChanged( section, setting ):
404 if verbose() : print "GENERICSOLVERGUI.preferenceChanged(): %s / %s" % ( section, setting )
407 # called when active view is changed
408 # view ID is passed as parameter
409 def activeViewChanged( viewID ):
410 if verbose() : print "GENERICSOLVERGUI.activeViewChanged(): %d" % viewID
413 # called when active view is cloned
414 # cloned view ID is passed as parameter
415 def viewCloned( viewID ):
416 if verbose() : print "GENERICSOLVERGUI.viewCloned(): %d" % viewID
419 # called when active view is viewClosed
420 # view ID is passed as parameter
421 def viewClosed( viewID ):
422 if verbose() : print "GENERICSOLVERGUI.viewClosed(): %d" % viewID
425 ################################################
426 # GUI actions implementation
427 ################################################
430 # 'SOLVER' dialog box
432 ##class MyDialog( QDialog ):
434 ## def __init__( self, parent = None, modal = 0):
435 ## QDialog.__init__( self, parent )
436 ## self.setObjectName( "MyDialog" )
437 ## self.setModal( modal )
438 ## self.setWindowTitle( "SOLVER!" )
439 ## vb = QVBoxLayout( self )
442 ## hb0 = QHBoxLayout( self )
443 ## label = QLabel( "Prenom: ", self )
444 ## hb0.addWidget( label )
445 ## self.entry = QLineEdit( self )
446 ## self.entry.setMinimumWidth( 200 )
447 ## hb0.addWidget( self.entry )
448 ## vb.addLayout( hb0 )
450 ## hb1 = QHBoxLayout( self )
451 ## bOk = QPushButton( "&OK", self )
452 ## self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
453 ## hb1.addWidget( bOk )
455 ## hb1.addStretch( 10 )
457 ## bCancel = QPushButton( "&Cancel", self )
458 ## self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
459 ## hb1.addWidget( bCancel )
461 ## vb.addLayout( hb1 )
465 ## def accept( self ):
466 ## name = str( self.entry.text() )
468 ## inPoint = [1, 2, 3]
470 ## print "GENERICSOLVERGUI.accept (1): inPoint = ", inPoint
471 ## print "GENERICSOLVERGUI.accept (1): outPoint = ", outPoint
472 ## (ok,outPoint) = getEngine().Exec( inPoint, outPoint )
473 ## QMessageBox.information( self, 'Info', "Exec() method returned %d" % ok )
474 ## print "GENERICSOLVERGUI.accept (2): inPoint = ", inPoint
475 ## print "GENERICSOLVERGUI.accept (2): outPoint = ", outPoint
478 ## QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
484 def addObjectInStudy( builder, father, objname, objid ):
485 obj = getSubSObjectByName( father, objname )
487 obj = builder.NewObject( father )
488 attr = builder.FindOrCreateAttribute( obj, "AttributeName" )
489 attr.SetValue( objname )
490 attr = builder.FindOrCreateAttribute( obj, "AttributeLocalID" )
491 attr.SetValue( objid )
494 def setValueToVariable( builder, varobj, value ):
495 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
497 if (objid == GUIcontext.VARIABLE_ID):
498 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
499 attr.SetValue( value )
501 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
502 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
505 def getValueOfVariable( builder, varobj ):
506 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
508 if (objid == GUIcontext.VARIABLE_ID):
509 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
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 getSubSObjectByName( sobjFather, childName ):
518 iter = study.NewChildIterator( sobjFather )
519 #builder = study.NewBuilder()
522 if sobj.GetName() == childName:
529 # Create a deterministic case
532 print "GENERICSOLVERGUI.CreateCase : enter"
533 default_case_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME ).trimmed() )
535 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
536 # request object name from the user
537 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
543 name = str( name.trimmed() )
544 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
545 # generate object name
548 name = "%s %d" % ( default_case_name, __id__ )
550 name = default_case_name
554 # generate object name
557 name = "%s %d" % ( default_case_name, __id__ )
561 builder = study.NewBuilder()
562 father = findOrCreateComponent()
563 case = addObjectInStudy( builder, father, name, GUIcontext.CASE_ID )
564 varE = addObjectInStudy( builder, case, "E", GUIcontext.VARIABLE_ID )
565 setValueToVariable( builder, varE, 210.e9 )
566 varF = addObjectInStudy( builder, case, "F", GUIcontext.VARIABLE_ID )
567 setValueToVariable( builder, varF, 1000. )
568 varL = addObjectInStudy( builder, case, "L", GUIcontext.VARIABLE_ID )
569 setValueToVariable( builder, varL, 1.5 )
570 varI = addObjectInStudy( builder, case, "I", GUIcontext.VARIABLE_ID )
571 setValueToVariable( builder, varI, 2.e-6 )
573 inputVarList = [study_exchange_vars.Variable("E"),
574 study_exchange_vars.Variable("F"),
575 study_exchange_vars.Variable("L"),
576 study_exchange_vars.Variable("I")]
577 outputVarList = [study_exchange_vars.Variable("dev")]
578 exchVars = study_exchange_vars.ExchangeVariables(inputVarList, outputVarList)
579 study_exchange_vars.createSObjectForExchangeVariables(case, exchVars, icon = VARS_ICON)
581 sg.updateObjBrowser( True )
582 print "GENERICSOLVERGUI.CreateCase : exit"
586 # Get the selected deterministic case
588 def GetSelectedCase():
589 entry = sg.getSelected( 0 )
592 sobj = study.FindObjectID( entry )
594 test, attr = sobj.FindAttribute( "AttributeLocalID" )
595 print "GENERICSOLVERGUI.GetSelectedCase : test=%d attr=%d" % (test,attr.Value())
596 if attr.Value() == GUIcontext.CASE_ID: # This is a case entry
597 if hasChildren( sobj ):
600 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no child for case"
603 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! not a case"
606 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! selected object not found in study"
609 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no selection"
613 # Retrieve data from selected case
615 def GetDataFromCase( caseEntry ):
618 case = study.FindObjectID( caseEntry )
619 builder = study.NewBuilder()
620 # Get the values of the variables and make them a list
621 for name in ("E", "F", "L", "I"):
622 var = getSubSObjectByName( case, name )
624 print "GENERICSOLVERGUI.GetDataFromCase : ERROR! no variable '%s'" % name
626 theCase.append( getValueOfVariable( builder, var ) )
630 # Add some variable to the case
632 def AddDataToCase( caseEntry, varName, varValue ):
634 case = study.FindObjectID( caseEntry )
635 builder = study.NewBuilder()
636 var = addObjectInStudy( builder, case, varName, GUIcontext.VARIABLE_ID )
637 setValueToVariable( builder, var, varValue )
638 sg.updateObjBrowser( True )
645 case = GetSelectedCase()
646 getEngine().Init( getStudyId(), case, "" )
648 inPoint = GetDataFromCase( case )[:2]
649 print "GENERICSOLVERGUI.RunSOLVER (1): inPoint = ", inPoint
650 (ok, outPoint) = getEngine().Exec(inPoint)
651 print "GENERICSOLVERGUI.RunSOLVER (2): inPoint = ", inPoint
652 print "GENERICSOLVERGUI.RunSOLVER (2): outPoint = ", outPoint
653 AddDataToCase( case, "Deviation", outPoint[0] )
655 getEngine().Finalize()
662 ##def CreateObject():
663 ## default_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME ).trimmed() )
665 ## if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
666 ## # request object name from the user
667 ## name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
669 ## "Enter object name:",
673 ## name = str( name.trimmed() )
674 ## elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
675 ## # generate object name
677 ## __id__ = __id__ + 1
678 ## name = "%s %d" % ( default_name, __id__ )
680 ## name = default_name
684 ## # generate object name
686 ## __id__ = __id__ + 1
687 ## name = "%s %d" % ( default_name, __id__ )
689 ## if not name: return
690 ## study = getStudy()
691 ## builder = study.NewBuilder()
692 ## father = findOrCreateComponent()
693 ## obj = addObjectInStudy( builder, father, name, GUIcontext.OBJECT_ID )
694 ## sg.updateObjBrowser( True )
702 father = study.FindComponent( GUIcontext.MODULE_NAME )
704 iter = study.NewChildIterator( father )
705 builder = study.NewBuilder()
709 builder.RemoveObjectWithChildren( sobj )
711 sg.updateObjBrowser( True )
720 entry = sg.getSelected( 0 )
722 sobj = study.FindObjectID( entry )
724 test, attr = sobj.FindAttribute( "AttributeName" )
726 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
733 # Delete selected object(s)
737 builder = study.NewBuilder()
738 if sg.SelectedCount() <= 0: return
739 for i in range( sg.SelectedCount() ):
740 entry = sg.getSelected( i )
742 sobj = study.FindObjectID( entry )
744 builder.RemoveObject( sobj )
748 sg.updateObjBrowser( True )
752 # Rename selected object
756 builder = study.NewBuilder()
757 entry = sg.getSelected( 0 )
759 sobj = study.FindObjectID( entry )
761 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
763 "Enter object name:",
766 name = str( name.trimmed() )
767 if not ok or not name: return
768 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
769 attr.SetValue( name )
770 sg.updateObjBrowser( True )
776 # Set value to variable
780 builder = study.NewBuilder()
781 entry = sg.getSelected( 0 )
783 sobj = study.FindObjectID( entry )
785 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
789 str(getValueOfVariable( builder, sobj)) )
790 value = float( name.trimmed() )
791 if not ok or not value: return
792 setValueToVariable( builder, sobj, value )
793 sg.updateObjBrowser( True )
799 # Commands dictionary
802 GUIcontext.SOLVER_ID : RunSOLVER,
803 GUIcontext.CREATE_CASE_ID : CreateCase,
804 ## GUIcontext.CREATE_OBJECT_ID : CreateObject,
805 GUIcontext.DELETE_ALL_ID : DeleteAll,
806 GUIcontext.SHOW_ME_ID : ShowMe,
807 GUIcontext.DELETE_ME_ID : Delete,
808 GUIcontext.RENAME_ME_ID : Rename,
809 GUIcontext.SET_VALUE_ID : SetValue,