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 ################################################
36 # Used to store actions, menus, toolbars, etc...
37 ################################################
41 MODULE_NAME = "GENERICSOLVER"
43 MODULE_PIXMAP = "GENERICSOLVER_small.png"
50 # menus/toolbars/actions IDs
51 GENERICSOLVER_MENU_ID = 90
53 CREATE_OBJECT_ID = 942
58 GENERICSOLVER_TB_ID = 90
66 DEFAULT_NAME = "Object"
67 DEFAULT_CASE_NAME = "Case"
71 # create top-level menu
72 mid = sgPyQt.createMenu( "Genericsolver", -1, GUIcontext.GENERICSOLVER_MENU_ID, sgPyQt.defaultMenuGroup() )
74 tid = sgPyQt.createTool( "Genericsolver" )
75 # create actions and fill menu and toolbar with actions
76 a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create a new case", "CaseGENERICSOLVER.png" )
77 sgPyQt.createMenu( a, mid )
78 sgPyQt.createTool( a, tid )
79 a = sgPyQt.createAction( GUIcontext.SOLVER_ID, "Run Solver", "Run Solver", "Run Solver on selected case", "ExecGENERICSOLVER.png" )
80 sgPyQt.createMenu( a, mid )
81 sgPyQt.createTool( a, tid )
82 a = sgPyQt.createSeparator()
83 sgPyQt.createMenu( a, mid )
84 #a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
85 #sgPyQt.createMenu( a, mid )
86 #a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create case" )
87 #sgPyQt.createMenu( a, mid )
88 a = sgPyQt.createSeparator()
89 sgPyQt.createMenu( a, mid )
91 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
92 ag.setText( "Creation mode" )
93 ag.setUsesDropDown(True)
94 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
95 a.setCheckable( True )
97 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
98 a.setCheckable( True )
100 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
101 a.setCheckable( True )
103 sgPyQt.createMenu( ag, mid )
104 sgPyQt.createTool( ag, tid )
105 default_mode = sgPyQt.integerSetting( "GENERICSOLVER", "creation_mode", 0 )
106 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
109 # the following action are used in context popup
110 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
111 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
112 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
113 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
114 a = sgPyQt.createAction( GUIcontext.SET_VALUE_ID, "Set value", "Set Value", "Set a new value to variable" )
118 ################################################
120 ################################################
122 # study-to-context map
123 __study2context__ = {}
125 __current_context__ = None
130 ################################################
132 # Get SALOME PyQt interface
134 sgPyQt = SalomePyQt.SalomePyQt()
136 # Get SALOME Swig interface
137 import libSALOME_Swig
138 sg = libSALOME_Swig.SALOMEGUI_Swig()
140 ################################################
142 ################################################
150 if __verbose__ is None:
152 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
160 # get GENERICSOLVER engine
163 engine = salome.lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
167 # get active study ID
170 return sgPyQt.getStudyId()
176 studyId = getStudyId()
177 study = salome.myStudyManager.GetStudyByID( studyId )
181 # returns True if object has children
183 def hasChildren( sobj ):
186 iter = study.NewChildIterator( sobj )
188 name = iter.Value().GetName()
197 # finds or creates component object
199 def findOrCreateComponent():
201 father = study.FindComponent( GUIcontext.MODULE_NAME )
203 builder = study.NewBuilder()
204 father = builder.NewComponent( GUIcontext.MODULE_NAME )
205 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
206 attr.SetValue( GUIcontext.MODULE_NAME )
207 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
208 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
209 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
210 attr.SetValue( GUIcontext.MODULE_ID )
212 builder.DefineComponentInstance( father, getEngine() )
220 # get current GUI context
223 global __current_context__
224 return __current_context__
227 # set and return current GUI context
228 # study ID is passed as parameter
230 def setContext( studyID ):
231 global __study2context__, __current_context__
232 if not __study2context__.has_key(studyID):
233 __study2context__[studyID] = GUIcontext()
235 __current_context__ = __study2context__[studyID]
236 return __current_context__
239 # increment object counter in the map
241 def _incObjToMap( m, id ):
242 if id not in m: m[id] = 0
250 selcount = sg.SelectedCount()
253 for i in range( selcount ):
254 entry = sg.getSelected( i )
256 sobj = study.FindObjectID( entry )
258 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
260 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
262 _incObjToMap( seltypes, ID )
267 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
269 return selcount, seltypes
271 ################################################
273 ################################################
275 # called when module is initialized
276 # perform initialization actions
278 if verbose() : print "GENERICSOLVERGUI.initialize() : study : %d" % getStudyId()
279 # set default preferences values
280 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_obj_name"):
281 sgPyQt.addSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME )
282 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_case_name"):
283 sgPyQt.addSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME )
284 if not sgPyQt.hasSetting( "GENERICSOLVER", "creation_mode"):
285 sgPyQt.addSetting( "GENERICSOLVER", "creation_mode", 0 )
288 # called when module is initialized
289 # return map of popup windows to be used by the module
291 if verbose() : print "GENERICSOLVERGUI.windows() : study : %d" % getStudyId()
293 wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
294 wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
297 # called when module is initialized
298 # return list of 2d/3d views to be used ny the module
300 if verbose() : print "GENERICSOLVERGUI.views() : study : %d" % getStudyId()
303 # called when module is initialized
304 # export module's preferences
305 def createPreferences():
306 if verbose() : print "GENERICSOLVERGUI.createPreferences() : study : %d" % getStudyId()
307 gid = sgPyQt.addPreference( "General" )
308 gid = sgPyQt.addPreference( "Object creation", gid )
309 pid = sgPyQt.addPreference( "Default object name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_obj_name" )
310 pid = sgPyQt.addPreference( "Default case name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_case_name" )
311 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "GENERICSOLVER", "creation_mode" )
312 strings = QStringList()
313 strings.append( "Default name" )
314 strings.append( "Generate name" )
315 strings.append( "Ask name" )
317 indexes.append( QVariant(0) )
318 indexes.append( QVariant(1) )
319 indexes.append( QVariant(2) )
320 sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
321 sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
324 # called when module is activated
325 # returns True if activating is successfull and False otherwise
327 if verbose() : print "GENERICSOLVERGUI.activate() : study : %d" % getStudyId()
328 ctx = setContext( getStudyId() )
331 # called when module is deactivated
333 if verbose() : print "GENERICSOLVERGUI.deactivate() : study : %d" % getStudyId()
336 # called when active study is changed
337 # active study ID is passed as parameter
338 def activeStudyChanged( studyID ):
339 if verbose() : print "GENERICSOLVERGUI.activeStudyChanged(): study : %d" % studyID
340 ctx = setContext( getStudyId() )
343 # called when popup menu is invoked
344 # popup menu and menu context are passed as parameters
345 def createPopupMenu( popup, context ):
346 if verbose() : print "GENERICSOLVERGUI.createPopupMenu(): context = %s" % context
347 ctx = setContext( getStudyId() )
349 selcount, selected = getSelection()
350 print selcount, selected
352 # one object is selected
353 if GUIcontext.MODULE_ID in selected:
355 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
356 ## elif GUIcontext.OBJECT_ID in selected:
358 ## popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
359 ## popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
360 ## popup.addSeparator()
361 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
362 elif GUIcontext.CASE_ID in selected:
364 popup.addAction( sgPyQt.action( GUIcontext.SOLVER_ID ) )
365 elif GUIcontext.VARIABLE_ID in selected:
367 popup.addAction( sgPyQt.action( GUIcontext.SET_VALUE_ID ) )
368 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
372 # several objects are selected
373 if len( selected ) == 1:
374 if GUIcontext.MODULE_ID in selected:
376 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
377 ## elif GUIcontext.OBJECT_ID in selected:
378 ## # menu for list of objects
379 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
385 # called when GUI action is activated
386 # action ID is passed as parameter
387 def OnGUIEvent( commandID ):
388 if verbose() : print "GENERICSOLVERGUI.OnGUIEvent(): command = %d" % commandID
389 if dict_command.has_key( commandID ):
391 dict_command[commandID]()
393 traceback.print_exc()
395 if verbose() : print "The command is not implemented: %d" % commandID
398 # called when module's preferences are changed
399 # preference's resources section and setting name are passed as parameters
400 def preferenceChanged( section, setting ):
401 if verbose() : print "GENERICSOLVERGUI.preferenceChanged(): %s / %s" % ( section, setting )
404 # called when active view is changed
405 # view ID is passed as parameter
406 def activeViewChanged( viewID ):
407 if verbose() : print "GENERICSOLVERGUI.activeViewChanged(): %d" % viewID
410 # called when active view is cloned
411 # cloned view ID is passed as parameter
412 def viewCloned( viewID ):
413 if verbose() : print "GENERICSOLVERGUI.viewCloned(): %d" % viewID
416 # called when active view is viewClosed
417 # view ID is passed as parameter
418 def viewClosed( viewID ):
419 if verbose() : print "GENERICSOLVERGUI.viewClosed(): %d" % viewID
422 ################################################
423 # GUI actions implementation
424 ################################################
427 # 'SOLVER' dialog box
429 ##class MyDialog( QDialog ):
431 ## def __init__( self, parent = None, modal = 0):
432 ## QDialog.__init__( self, parent )
433 ## self.setObjectName( "MyDialog" )
434 ## self.setModal( modal )
435 ## self.setWindowTitle( "SOLVER!" )
436 ## vb = QVBoxLayout( self )
439 ## hb0 = QHBoxLayout( self )
440 ## label = QLabel( "Prenom: ", self )
441 ## hb0.addWidget( label )
442 ## self.entry = QLineEdit( self )
443 ## self.entry.setMinimumWidth( 200 )
444 ## hb0.addWidget( self.entry )
445 ## vb.addLayout( hb0 )
447 ## hb1 = QHBoxLayout( self )
448 ## bOk = QPushButton( "&OK", self )
449 ## self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
450 ## hb1.addWidget( bOk )
452 ## hb1.addStretch( 10 )
454 ## bCancel = QPushButton( "&Cancel", self )
455 ## self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
456 ## hb1.addWidget( bCancel )
458 ## vb.addLayout( hb1 )
462 ## def accept( self ):
463 ## name = str( self.entry.text() )
465 ## inPoint = [1, 2, 3]
467 ## print "GENERICSOLVERGUI.accept (1): inPoint = ", inPoint
468 ## print "GENERICSOLVERGUI.accept (1): outPoint = ", outPoint
469 ## (ok,outPoint) = getEngine().Exec( inPoint, outPoint )
470 ## QMessageBox.information( self, 'Info', "Exec() method returned %d" % ok )
471 ## print "GENERICSOLVERGUI.accept (2): inPoint = ", inPoint
472 ## print "GENERICSOLVERGUI.accept (2): outPoint = ", outPoint
475 ## QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
481 def addObjectInStudy( builder, father, objname, objid ):
482 obj = getSubSObjectByName( father, objname )
484 obj = builder.NewObject( father )
485 attr = builder.FindOrCreateAttribute( obj, "AttributeName" )
486 attr.SetValue( objname )
487 attr = builder.FindOrCreateAttribute( obj, "AttributeLocalID" )
488 attr.SetValue( objid )
491 def setValueToVariable( builder, varobj, value ):
492 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
494 if (objid == GUIcontext.VARIABLE_ID):
495 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
496 attr.SetValue( value )
498 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
499 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
502 def getValueOfVariable( builder, varobj ):
503 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
505 if (objid == GUIcontext.VARIABLE_ID):
506 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
509 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
510 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
513 def getSubSObjectByName( sobjFather, childName ):
515 iter = study.NewChildIterator( sobjFather )
516 #builder = study.NewBuilder()
519 if sobj.GetName() == childName:
526 # Create a deterministic case
529 print "GENERICSOLVERGUI.CreateCase : enter"
530 default_case_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME ).trimmed() )
532 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
533 # request object name from the user
534 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
540 name = str( name.trimmed() )
541 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
542 # generate object name
545 name = "%s %d" % ( default_case_name, __id__ )
547 name = default_case_name
551 # generate object name
554 name = "%s %d" % ( default_case_name, __id__ )
558 builder = study.NewBuilder()
559 father = findOrCreateComponent()
560 case = addObjectInStudy( builder, father, name, GUIcontext.CASE_ID )
561 varE = addObjectInStudy( builder, case, "E", GUIcontext.VARIABLE_ID )
562 setValueToVariable( builder, varE, 210.e9 )
563 varF = addObjectInStudy( builder, case, "F", GUIcontext.VARIABLE_ID )
564 setValueToVariable( builder, varF, 1000. )
565 varL = addObjectInStudy( builder, case, "L", GUIcontext.VARIABLE_ID )
566 setValueToVariable( builder, varL, 1.5 )
567 varI = addObjectInStudy( builder, case, "I", GUIcontext.VARIABLE_ID )
568 setValueToVariable( builder, varI, 2.e-6 )
569 sg.updateObjBrowser( True )
570 print "GENERICSOLVERGUI.CreateCase : exit"
574 # Get the selected deterministic case
576 def GetSelectedCase():
577 entry = sg.getSelected( 0 )
580 sobj = study.FindObjectID( entry )
582 test, attr = sobj.FindAttribute( "AttributeLocalID" )
583 print "GENERICSOLVERGUI.GetSelectedCase : test=%d attr=%d" % (test,attr.Value())
584 if attr.Value() == GUIcontext.CASE_ID: # This is a case entry
585 if hasChildren( sobj ):
588 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no child for case"
591 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! not a case"
594 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! selected object not found in study"
597 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no selection"
601 # Retrieve data from selected case
603 def GetDataFromCase( caseEntry ):
606 case = study.FindObjectID( caseEntry )
607 builder = study.NewBuilder()
608 # Get the values of the variables and make them a list
609 for name in ("E", "F", "L", "I"):
610 var = getSubSObjectByName( case, name )
612 print "GENERICSOLVERGUI.GetDataFromCase : ERROR! no variable '%s'" % name
614 theCase.append( getValueOfVariable( builder, var ) )
618 # Add some variable to the case
620 def AddDataToCase( caseEntry, varName, varValue ):
622 case = study.FindObjectID( caseEntry )
623 builder = study.NewBuilder()
624 var = addObjectInStudy( builder, case, varName, GUIcontext.VARIABLE_ID )
625 setValueToVariable( builder, var, varValue )
626 sg.updateObjBrowser( True )
633 case = GetSelectedCase()
634 getEngine().Init( getStudyId(), case, "" )
636 inPoint = GetDataFromCase( case )[:2]
637 print "GENERICSOLVERGUI.RunSOLVER (1): inPoint = ", inPoint
638 (ok, outPoint) = getEngine().Exec(inPoint)
639 print "GENERICSOLVERGUI.RunSOLVER (2): inPoint = ", inPoint
640 print "GENERICSOLVERGUI.RunSOLVER (2): outPoint = ", outPoint
641 AddDataToCase( case, "Deviation", outPoint[0] )
643 getEngine().Finalize()
650 ##def CreateObject():
651 ## default_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME ).trimmed() )
653 ## if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
654 ## # request object name from the user
655 ## name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
657 ## "Enter object name:",
661 ## name = str( name.trimmed() )
662 ## elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
663 ## # generate object name
665 ## __id__ = __id__ + 1
666 ## name = "%s %d" % ( default_name, __id__ )
668 ## name = default_name
672 ## # generate object name
674 ## __id__ = __id__ + 1
675 ## name = "%s %d" % ( default_name, __id__ )
677 ## if not name: return
678 ## study = getStudy()
679 ## builder = study.NewBuilder()
680 ## father = findOrCreateComponent()
681 ## obj = addObjectInStudy( builder, father, name, GUIcontext.OBJECT_ID )
682 ## sg.updateObjBrowser( True )
690 father = study.FindComponent( GUIcontext.MODULE_NAME )
692 iter = study.NewChildIterator( father )
693 builder = study.NewBuilder()
697 builder.RemoveObjectWithChildren( sobj )
699 sg.updateObjBrowser( True )
708 entry = sg.getSelected( 0 )
710 sobj = study.FindObjectID( entry )
712 test, attr = sobj.FindAttribute( "AttributeName" )
714 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
721 # Delete selected object(s)
725 builder = study.NewBuilder()
726 if sg.SelectedCount() <= 0: return
727 for i in range( sg.SelectedCount() ):
728 entry = sg.getSelected( i )
730 sobj = study.FindObjectID( entry )
732 builder.RemoveObject( sobj )
736 sg.updateObjBrowser( True )
740 # Rename selected object
744 builder = study.NewBuilder()
745 entry = sg.getSelected( 0 )
747 sobj = study.FindObjectID( entry )
749 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
751 "Enter object name:",
754 name = str( name.trimmed() )
755 if not ok or not name: return
756 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
757 attr.SetValue( name )
758 sg.updateObjBrowser( True )
764 # Set value to variable
768 builder = study.NewBuilder()
769 entry = sg.getSelected( 0 )
771 sobj = study.FindObjectID( entry )
773 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
777 str(getValueOfVariable( builder, sobj)) )
778 value = float( name.trimmed() )
779 if not ok or not value: return
780 setValueToVariable( builder, sobj, value )
781 sg.updateObjBrowser( True )
787 # Commands dictionary
790 GUIcontext.SOLVER_ID : RunSOLVER,
791 GUIcontext.CREATE_CASE_ID : CreateCase,
792 ## GUIcontext.CREATE_OBJECT_ID : CreateObject,
793 GUIcontext.DELETE_ALL_ID : DeleteAll,
794 GUIcontext.SHOW_ME_ID : ShowMe,
795 GUIcontext.DELETE_ME_ID : Delete,
796 GUIcontext.RENAME_ME_ID : Rename,
797 GUIcontext.SET_VALUE_ID : SetValue,