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
25 from PyQt4.QtGui import *
26 from PyQt4.QtCore import *
30 import GENERICSOLVER_ORB
34 VARS_ICON = "icon_variables.png"
36 ################################################
38 # Used to store actions, menus, toolbars, etc...
39 ################################################
43 MODULE_NAME = "GENERICSOLVER"
45 MODULE_PIXMAP = "GENERICSOLVER_small.png"
52 # menus/toolbars/actions IDs
53 GENERICSOLVER_MENU_ID = 90
55 CREATE_OBJECT_ID = 942
60 GENERICSOLVER_TB_ID = 90
68 DEFAULT_NAME = "Object"
69 DEFAULT_CASE_NAME = "Case"
73 # create top-level menu
74 mid = sgPyQt.createMenu( "Genericsolver", -1, GUIcontext.GENERICSOLVER_MENU_ID, sgPyQt.defaultMenuGroup() )
76 tid = sgPyQt.createTool( "Genericsolver" )
77 # create actions and fill menu and toolbar with actions
78 a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create a new case", "CaseGENERICSOLVER.png" )
79 sgPyQt.createMenu( a, mid )
80 sgPyQt.createTool( a, tid )
81 a = sgPyQt.createAction( GUIcontext.SOLVER_ID, "Run Solver", "Run Solver", "Run Solver on selected case", "ExecGENERICSOLVER.png" )
82 sgPyQt.createMenu( a, mid )
83 sgPyQt.createTool( a, tid )
84 a = sgPyQt.createSeparator()
85 sgPyQt.createMenu( a, mid )
86 #a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
87 #sgPyQt.createMenu( a, mid )
88 #a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create case" )
89 #sgPyQt.createMenu( a, mid )
90 a = sgPyQt.createSeparator()
91 sgPyQt.createMenu( a, mid )
93 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
94 ag.setText( "Creation mode" )
95 ag.setUsesDropDown(True)
96 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
97 a.setCheckable( True )
99 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
100 a.setCheckable( True )
102 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
103 a.setCheckable( True )
105 sgPyQt.createMenu( ag, mid )
106 sgPyQt.createTool( ag, tid )
107 default_mode = sgPyQt.integerSetting( "GENERICSOLVER", "creation_mode", 0 )
108 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
111 # the following action are used in context popup
112 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
113 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
114 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
115 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
116 a = sgPyQt.createAction( GUIcontext.SET_VALUE_ID, "Set value", "Set Value", "Set a new value to variable" )
120 ################################################
122 ################################################
124 # study-to-context map
125 __study2context__ = {}
127 __current_context__ = None
132 ################################################
134 # Get SALOME PyQt interface
136 sgPyQt = SalomePyQt.SalomePyQt()
138 # Get SALOME Swig interface
139 import libSALOME_Swig
140 sg = libSALOME_Swig.SALOMEGUI_Swig()
142 ################################################
144 ################################################
152 if __verbose__ is None:
154 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
162 # get GENERICSOLVER engine
165 engine = salome.lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
169 # get active study ID
172 return sgPyQt.getStudyId()
178 studyId = getStudyId()
179 study = salome.myStudyManager.GetStudyByID( studyId )
183 # returns True if object has children
185 def hasChildren( sobj ):
188 iter = study.NewChildIterator( sobj )
190 name = iter.Value().GetName()
199 # finds or creates component object
201 def findOrCreateComponent():
203 father = study.FindComponent( GUIcontext.MODULE_NAME )
205 builder = study.NewBuilder()
206 father = builder.NewComponent( GUIcontext.MODULE_NAME )
207 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
208 attr.SetValue( GUIcontext.MODULE_NAME )
209 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
210 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
211 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
212 attr.SetValue( GUIcontext.MODULE_ID )
214 builder.DefineComponentInstance( father, getEngine() )
222 # get current GUI context
225 global __current_context__
226 return __current_context__
229 # set and return current GUI context
230 # study ID is passed as parameter
232 def setContext( studyID ):
233 global __study2context__, __current_context__
234 if not __study2context__.has_key(studyID):
235 __study2context__[studyID] = GUIcontext()
237 __current_context__ = __study2context__[studyID]
238 return __current_context__
241 # increment object counter in the map
243 def _incObjToMap( m, id ):
244 if id not in m: m[id] = 0
252 selcount = sg.SelectedCount()
255 for i in range( selcount ):
256 entry = sg.getSelected( i )
258 sobj = study.FindObjectID( entry )
260 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
262 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
264 _incObjToMap( seltypes, ID )
269 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
271 return selcount, seltypes
273 ################################################
275 ################################################
277 # called when module is initialized
278 # perform initialization actions
280 if verbose() : print "GENERICSOLVERGUI.initialize() : study : %d" % getStudyId()
281 # set default preferences values
282 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_obj_name"):
283 sgPyQt.addSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME )
284 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_case_name"):
285 sgPyQt.addSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME )
286 if not sgPyQt.hasSetting( "GENERICSOLVER", "creation_mode"):
287 sgPyQt.addSetting( "GENERICSOLVER", "creation_mode", 0 )
290 # called when module is initialized
291 # return map of popup windows to be used by the module
293 if verbose() : print "GENERICSOLVERGUI.windows() : study : %d" % getStudyId()
295 wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
296 wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
299 # called when module is initialized
300 # return list of 2d/3d views to be used ny the module
302 if verbose() : print "GENERICSOLVERGUI.views() : study : %d" % getStudyId()
305 # called when module is initialized
306 # export module's preferences
307 def createPreferences():
308 if verbose() : print "GENERICSOLVERGUI.createPreferences() : study : %d" % getStudyId()
309 gid = sgPyQt.addPreference( "General" )
310 gid = sgPyQt.addPreference( "Object creation", gid )
311 pid = sgPyQt.addPreference( "Default object name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_obj_name" )
312 pid = sgPyQt.addPreference( "Default case name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_case_name" )
313 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "GENERICSOLVER", "creation_mode" )
314 strings = QStringList()
315 strings.append( "Default name" )
316 strings.append( "Generate name" )
317 strings.append( "Ask name" )
319 indexes.append( QVariant(0) )
320 indexes.append( QVariant(1) )
321 indexes.append( QVariant(2) )
322 sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
323 sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
326 # called when module is activated
327 # returns True if activating is successfull and False otherwise
329 if verbose() : print "GENERICSOLVERGUI.activate() : study : %d" % getStudyId()
330 ctx = setContext( getStudyId() )
333 # called when module is deactivated
335 if verbose() : print "GENERICSOLVERGUI.deactivate() : study : %d" % getStudyId()
338 # called when active study is changed
339 # active study ID is passed as parameter
340 def activeStudyChanged( studyID ):
341 if verbose() : print "GENERICSOLVERGUI.activeStudyChanged(): study : %d" % studyID
342 ctx = setContext( getStudyId() )
345 # called when popup menu is invoked
346 # popup menu and menu context are passed as parameters
347 def createPopupMenu( popup, context ):
348 if verbose() : print "GENERICSOLVERGUI.createPopupMenu(): context = %s" % context
349 ctx = setContext( getStudyId() )
351 selcount, selected = getSelection()
352 print selcount, selected
354 # one object is selected
355 if GUIcontext.MODULE_ID in selected:
357 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
358 ## elif GUIcontext.OBJECT_ID in selected:
360 ## popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
361 ## popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
362 ## popup.addSeparator()
363 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
364 elif GUIcontext.CASE_ID in selected:
366 popup.addAction( sgPyQt.action( GUIcontext.SOLVER_ID ) )
367 elif GUIcontext.VARIABLE_ID in selected:
369 popup.addAction( sgPyQt.action( GUIcontext.SET_VALUE_ID ) )
370 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
374 # several objects are selected
375 if len( selected ) == 1:
376 if GUIcontext.MODULE_ID in selected:
378 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
379 ## elif GUIcontext.OBJECT_ID in selected:
380 ## # menu for list of objects
381 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
387 # called when GUI action is activated
388 # action ID is passed as parameter
389 def OnGUIEvent( commandID ):
390 if verbose() : print "GENERICSOLVERGUI.OnGUIEvent(): command = %d" % commandID
391 if dict_command.has_key( commandID ):
393 dict_command[commandID]()
395 traceback.print_exc()
397 if verbose() : print "The command is not implemented: %d" % commandID
400 # called when module's preferences are changed
401 # preference's resources section and setting name are passed as parameters
402 def preferenceChanged( section, setting ):
403 if verbose() : print "GENERICSOLVERGUI.preferenceChanged(): %s / %s" % ( section, setting )
406 # called when active view is changed
407 # view ID is passed as parameter
408 def activeViewChanged( viewID ):
409 if verbose() : print "GENERICSOLVERGUI.activeViewChanged(): %d" % viewID
412 # called when active view is cloned
413 # cloned view ID is passed as parameter
414 def viewCloned( viewID ):
415 if verbose() : print "GENERICSOLVERGUI.viewCloned(): %d" % viewID
418 # called when active view is viewClosed
419 # view ID is passed as parameter
420 def viewClosed( viewID ):
421 if verbose() : print "GENERICSOLVERGUI.viewClosed(): %d" % viewID
424 ################################################
425 # GUI actions implementation
426 ################################################
429 # 'SOLVER' dialog box
431 ##class MyDialog( QDialog ):
433 ## def __init__( self, parent = None, modal = 0):
434 ## QDialog.__init__( self, parent )
435 ## self.setObjectName( "MyDialog" )
436 ## self.setModal( modal )
437 ## self.setWindowTitle( "SOLVER!" )
438 ## vb = QVBoxLayout( self )
441 ## hb0 = QHBoxLayout( self )
442 ## label = QLabel( "Prenom: ", self )
443 ## hb0.addWidget( label )
444 ## self.entry = QLineEdit( self )
445 ## self.entry.setMinimumWidth( 200 )
446 ## hb0.addWidget( self.entry )
447 ## vb.addLayout( hb0 )
449 ## hb1 = QHBoxLayout( self )
450 ## bOk = QPushButton( "&OK", self )
451 ## self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
452 ## hb1.addWidget( bOk )
454 ## hb1.addStretch( 10 )
456 ## bCancel = QPushButton( "&Cancel", self )
457 ## self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
458 ## hb1.addWidget( bCancel )
460 ## vb.addLayout( hb1 )
464 ## def accept( self ):
465 ## name = str( self.entry.text() )
467 ## inPoint = [1, 2, 3]
469 ## print "GENERICSOLVERGUI.accept (1): inPoint = ", inPoint
470 ## print "GENERICSOLVERGUI.accept (1): outPoint = ", outPoint
471 ## (ok,outPoint) = getEngine().Exec( inPoint, outPoint )
472 ## QMessageBox.information( self, 'Info', "Exec() method returned %d" % ok )
473 ## print "GENERICSOLVERGUI.accept (2): inPoint = ", inPoint
474 ## print "GENERICSOLVERGUI.accept (2): outPoint = ", outPoint
477 ## QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
483 def addObjectInStudy( builder, father, objname, objid ):
484 obj = getSubSObjectByName( father, objname )
486 obj = builder.NewObject( father )
487 attr = builder.FindOrCreateAttribute( obj, "AttributeName" )
488 attr.SetValue( objname )
489 attr = builder.FindOrCreateAttribute( obj, "AttributeLocalID" )
490 attr.SetValue( objid )
493 def setValueToVariable( builder, varobj, value ):
494 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
496 if (objid == GUIcontext.VARIABLE_ID):
497 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
498 attr.SetValue( value )
500 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
501 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
504 def getValueOfVariable( builder, varobj ):
505 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
507 if (objid == GUIcontext.VARIABLE_ID):
508 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
511 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
512 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
515 def getSubSObjectByName( sobjFather, childName ):
517 iter = study.NewChildIterator( sobjFather )
518 #builder = study.NewBuilder()
521 if sobj.GetName() == childName:
528 # Create a deterministic case
531 print "GENERICSOLVERGUI.CreateCase : enter"
532 default_case_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME ).trimmed() )
534 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
535 # request object name from the user
536 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
542 name = str( name.trimmed() )
543 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
544 # generate object name
547 name = "%s %d" % ( default_case_name, __id__ )
549 name = default_case_name
553 # generate object name
556 name = "%s %d" % ( default_case_name, __id__ )
560 builder = study.NewBuilder()
561 father = findOrCreateComponent()
562 case = addObjectInStudy( builder, father, name, GUIcontext.CASE_ID )
563 varE = addObjectInStudy( builder, case, "E", GUIcontext.VARIABLE_ID )
564 setValueToVariable( builder, varE, 210.e9 )
565 varF = addObjectInStudy( builder, case, "F", GUIcontext.VARIABLE_ID )
566 setValueToVariable( builder, varF, 1000. )
567 varL = addObjectInStudy( builder, case, "L", GUIcontext.VARIABLE_ID )
568 setValueToVariable( builder, varL, 1.5 )
569 varI = addObjectInStudy( builder, case, "I", GUIcontext.VARIABLE_ID )
570 setValueToVariable( builder, varI, 2.e-6 )
572 from salome.kernel import varlist
573 exchVars = varlist.ExchangeVariables(inputVarList = [varlist.Variable("E"),
574 varlist.Variable("F"),
575 varlist.Variable("L"),
576 varlist.Variable("I")],
577 outputVarList = [varlist.Variable("dev")])
578 varlist.createSObjectForExchangeVariables(case, exchVars, icon = VARS_ICON)
580 sg.updateObjBrowser( True )
581 print "GENERICSOLVERGUI.CreateCase : exit"
585 # Get the selected deterministic case
587 def GetSelectedCase():
588 entry = sg.getSelected( 0 )
591 sobj = study.FindObjectID( entry )
593 test, attr = sobj.FindAttribute( "AttributeLocalID" )
594 print "GENERICSOLVERGUI.GetSelectedCase : test=%d attr=%d" % (test,attr.Value())
595 if attr.Value() == GUIcontext.CASE_ID: # This is a case entry
596 if hasChildren( sobj ):
599 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no child for case"
602 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! not a case"
605 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! selected object not found in study"
608 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no selection"
612 # Retrieve data from selected case
614 def GetDataFromCase( caseEntry ):
617 case = study.FindObjectID( caseEntry )
618 builder = study.NewBuilder()
619 # Get the values of the variables and make them a list
620 for name in ("E", "F", "L", "I"):
621 var = getSubSObjectByName( case, name )
623 print "GENERICSOLVERGUI.GetDataFromCase : ERROR! no variable '%s'" % name
625 theCase.append( getValueOfVariable( builder, var ) )
629 # Add some variable to the case
631 def AddDataToCase( caseEntry, varName, varValue ):
633 case = study.FindObjectID( caseEntry )
634 builder = study.NewBuilder()
635 var = addObjectInStudy( builder, case, varName, GUIcontext.VARIABLE_ID )
636 setValueToVariable( builder, var, varValue )
637 sg.updateObjBrowser( True )
644 case = GetSelectedCase()
645 getEngine().Init( getStudyId(), case, "" )
647 inPoint = GetDataFromCase( case )[:2]
648 print "GENERICSOLVERGUI.RunSOLVER (1): inPoint = ", inPoint
649 (ok, outPoint) = getEngine().Exec(inPoint)
650 print "GENERICSOLVERGUI.RunSOLVER (2): inPoint = ", inPoint
651 print "GENERICSOLVERGUI.RunSOLVER (2): outPoint = ", outPoint
652 AddDataToCase( case, "Deviation", outPoint[0] )
654 getEngine().Finalize()
661 ##def CreateObject():
662 ## default_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME ).trimmed() )
664 ## if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
665 ## # request object name from the user
666 ## name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
668 ## "Enter object name:",
672 ## name = str( name.trimmed() )
673 ## elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
674 ## # generate object name
676 ## __id__ = __id__ + 1
677 ## name = "%s %d" % ( default_name, __id__ )
679 ## name = default_name
683 ## # generate object name
685 ## __id__ = __id__ + 1
686 ## name = "%s %d" % ( default_name, __id__ )
688 ## if not name: return
689 ## study = getStudy()
690 ## builder = study.NewBuilder()
691 ## father = findOrCreateComponent()
692 ## obj = addObjectInStudy( builder, father, name, GUIcontext.OBJECT_ID )
693 ## sg.updateObjBrowser( True )
701 father = study.FindComponent( GUIcontext.MODULE_NAME )
703 iter = study.NewChildIterator( father )
704 builder = study.NewBuilder()
708 builder.RemoveObjectWithChildren( sobj )
710 sg.updateObjBrowser( True )
719 entry = sg.getSelected( 0 )
721 sobj = study.FindObjectID( entry )
723 test, attr = sobj.FindAttribute( "AttributeName" )
725 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
732 # Delete selected object(s)
736 builder = study.NewBuilder()
737 if sg.SelectedCount() <= 0: return
738 for i in range( sg.SelectedCount() ):
739 entry = sg.getSelected( i )
741 sobj = study.FindObjectID( entry )
743 builder.RemoveObject( sobj )
747 sg.updateObjBrowser( True )
751 # Rename selected object
755 builder = study.NewBuilder()
756 entry = sg.getSelected( 0 )
758 sobj = study.FindObjectID( entry )
760 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
762 "Enter object name:",
765 name = str( name.trimmed() )
766 if not ok or not name: return
767 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
768 attr.SetValue( name )
769 sg.updateObjBrowser( True )
775 # Set value to variable
779 builder = study.NewBuilder()
780 entry = sg.getSelected( 0 )
782 sobj = study.FindObjectID( entry )
784 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
788 str(getValueOfVariable( builder, sobj)) )
789 value = float( name.trimmed() )
790 if not ok or not value: return
791 setValueToVariable( builder, sobj, value )
792 sg.updateObjBrowser( True )
798 # Commands dictionary
801 GUIcontext.SOLVER_ID : RunSOLVER,
802 GUIcontext.CREATE_CASE_ID : CreateCase,
803 ## GUIcontext.CREATE_OBJECT_ID : CreateObject,
804 GUIcontext.DELETE_ALL_ID : DeleteAll,
805 GUIcontext.SHOW_ME_ID : ShowMe,
806 GUIcontext.DELETE_ME_ID : Delete,
807 GUIcontext.RENAME_ME_ID : Rename,
808 GUIcontext.SET_VALUE_ID : SetValue,