1 # Copyright (C) 2007-2010 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 : GENERICSOLVERGUI.py
24 # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
32 from PyQt4.QtGui import *
33 from PyQt4.QtCore import *
37 import GENERICSOLVER_ORB
41 ################################################
43 # Used to store actions, menus, toolbars, etc...
44 ################################################
48 MODULE_NAME = "GENERICSOLVER"
50 MODULE_PIXMAP = "GENERICSOLVER_small.png"
57 # menus/toolbars/actions IDs
58 GENERICSOLVER_MENU_ID = 90
60 CREATE_OBJECT_ID = 942
65 GENERICSOLVER_TB_ID = 90
73 DEFAULT_NAME = "Object"
74 DEFAULT_CASE_NAME = "Case"
78 # create top-level menu
79 mid = sgPyQt.createMenu( "Genericsolver", -1, GUIcontext.GENERICSOLVER_MENU_ID, sgPyQt.defaultMenuGroup() )
81 tid = sgPyQt.createTool( "Genericsolver" )
82 # create actions and fill menu and toolbar with actions
83 a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create a new case", "CaseGENERICSOLVER.png" )
84 sgPyQt.createMenu( a, mid )
85 sgPyQt.createTool( a, tid )
86 a = sgPyQt.createAction( GUIcontext.SOLVER_ID, "Run Solver", "Run Solver", "Run Solver on selected case", "ExecGENERICSOLVER.png" )
87 sgPyQt.createMenu( a, mid )
88 sgPyQt.createTool( a, tid )
89 a = sgPyQt.createSeparator()
90 sgPyQt.createMenu( a, mid )
91 #a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
92 #sgPyQt.createMenu( a, mid )
93 #a = sgPyQt.createAction( GUIcontext.CREATE_CASE_ID, "Create case", "Create case", "Create case" )
94 #sgPyQt.createMenu( a, mid )
95 a = sgPyQt.createSeparator()
96 sgPyQt.createMenu( a, mid )
98 ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
99 ag.setText( "Creation mode" )
100 ag.setUsesDropDown(True)
101 a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
102 a.setCheckable( True )
104 a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
105 a.setCheckable( True )
107 a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
108 a.setCheckable( True )
110 sgPyQt.createMenu( ag, mid )
111 sgPyQt.createTool( ag, tid )
112 default_mode = sgPyQt.integerSetting( "GENERICSOLVER", "creation_mode", 0 )
113 sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
116 # the following action are used in context popup
117 a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
118 a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID, "Show", "Show", "Show object name" )
119 a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID, "Delete", "Delete", "Remove object" )
120 a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID, "Rename", "Rename", "Rename object" )
121 a = sgPyQt.createAction( GUIcontext.SET_VALUE_ID, "Set value", "Set Value", "Set a new value to variable" )
125 ################################################
127 ################################################
129 # study-to-context map
130 __study2context__ = {}
132 __current_context__ = None
137 ################################################
139 # Get SALOME PyQt interface
141 sgPyQt = SalomePyQt.SalomePyQt()
143 # Get SALOME Swig interface
144 import libSALOME_Swig
145 sg = libSALOME_Swig.SALOMEGUI_Swig()
147 ################################################
149 ################################################
157 if __verbose__ is None:
159 __verbose__ = int( os.getenv('SALOME_VERBOSE', 0) )
167 # get GENERICSOLVER engine
170 engine = salome.lcc.FindOrLoadComponent( "FactoryServerPy", GUIcontext.MODULE_NAME )
174 # get active study ID
177 return sgPyQt.getStudyId()
183 studyId = getStudyId()
184 study = salome.myStudyManager.GetStudyByID( studyId )
188 # returns True if object has children
190 def hasChildren( sobj ):
193 iter = study.NewChildIterator( sobj )
195 name = iter.Value().GetName()
204 # finds or creates component object
206 def findOrCreateComponent():
208 father = study.FindComponent( GUIcontext.MODULE_NAME )
210 builder = study.NewBuilder()
211 father = builder.NewComponent( GUIcontext.MODULE_NAME )
212 attr = builder.FindOrCreateAttribute( father, "AttributeName" )
213 attr.SetValue( GUIcontext.MODULE_NAME )
214 attr = builder.FindOrCreateAttribute( father, "AttributePixMap" )
215 attr.SetPixMap( GUIcontext.MODULE_PIXMAP )
216 attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" )
217 attr.SetValue( GUIcontext.MODULE_ID )
219 builder.DefineComponentInstance( father, getEngine() )
227 # get current GUI context
230 global __current_context__
231 return __current_context__
234 # set and return current GUI context
235 # study ID is passed as parameter
237 def setContext( studyID ):
238 global __study2context__, __current_context__
239 if not __study2context__.has_key(studyID):
240 __study2context__[studyID] = GUIcontext()
242 __current_context__ = __study2context__[studyID]
243 return __current_context__
246 # increment object counter in the map
248 def _incObjToMap( m, id ):
249 if id not in m: m[id] = 0
257 selcount = sg.SelectedCount()
260 for i in range( selcount ):
261 entry = sg.getSelected( i )
263 sobj = study.FindObjectID( entry )
265 test, anAttr = sobj.FindAttribute( "AttributeLocalID" )
267 ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value()
269 _incObjToMap( seltypes, ID )
274 _incObjToMap( seltypes, GUIcontext.FOREIGN_ID )
276 return selcount, seltypes
278 ################################################
280 ################################################
282 # called when module is initialized
283 # perform initialization actions
285 if verbose() : print "GENERICSOLVERGUI.initialize() : study : %d" % getStudyId()
286 # set default preferences values
287 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_obj_name"):
288 sgPyQt.addSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME )
289 if not sgPyQt.hasSetting( "GENERICSOLVER", "def_case_name"):
290 sgPyQt.addSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME )
291 if not sgPyQt.hasSetting( "GENERICSOLVER", "creation_mode"):
292 sgPyQt.addSetting( "GENERICSOLVER", "creation_mode", 0 )
295 # called when module is initialized
296 # return map of popup windows to be used by the module
298 if verbose() : print "GENERICSOLVERGUI.windows() : study : %d" % getStudyId()
300 wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
301 wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
304 # called when module is initialized
305 # return list of 2d/3d views to be used ny the module
307 if verbose() : print "GENERICSOLVERGUI.views() : study : %d" % getStudyId()
310 # called when module is initialized
311 # export module's preferences
312 def createPreferences():
313 if verbose() : print "GENERICSOLVERGUI.createPreferences() : study : %d" % getStudyId()
314 gid = sgPyQt.addPreference( "General" )
315 gid = sgPyQt.addPreference( "Object creation", gid )
316 pid = sgPyQt.addPreference( "Default object name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_obj_name" )
317 pid = sgPyQt.addPreference( "Default case name", gid, SalomePyQt.PT_String, "GENERICSOLVER", "def_case_name" )
318 pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "GENERICSOLVER", "creation_mode" )
319 strings = QStringList()
320 strings.append( "Default name" )
321 strings.append( "Generate name" )
322 strings.append( "Ask name" )
324 indexes.append( QVariant(0) )
325 indexes.append( QVariant(1) )
326 indexes.append( QVariant(2) )
327 sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
328 sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
331 # called when module is activated
332 # returns True if activating is successfull and False otherwise
334 if verbose() : print "GENERICSOLVERGUI.activate() : study : %d" % getStudyId()
335 ctx = setContext( getStudyId() )
338 # called when module is deactivated
340 if verbose() : print "GENERICSOLVERGUI.deactivate() : study : %d" % getStudyId()
343 # called when active study is changed
344 # active study ID is passed as parameter
345 def activeStudyChanged( studyID ):
346 if verbose() : print "GENERICSOLVERGUI.activeStudyChanged(): study : %d" % studyID
347 ctx = setContext( getStudyId() )
350 # called when popup menu is invoked
351 # popup menu and menu context are passed as parameters
352 def createPopupMenu( popup, context ):
353 if verbose() : print "GENERICSOLVERGUI.createPopupMenu(): context = %s" % context
354 ctx = setContext( getStudyId() )
356 selcount, selected = getSelection()
357 print selcount, selected
359 # one object is selected
360 if GUIcontext.MODULE_ID in selected:
362 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
363 ## elif GUIcontext.OBJECT_ID in selected:
365 ## popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
366 ## popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
367 ## popup.addSeparator()
368 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
369 elif GUIcontext.CASE_ID in selected:
371 popup.addAction( sgPyQt.action( GUIcontext.SOLVER_ID ) )
372 elif GUIcontext.VARIABLE_ID in selected:
374 popup.addAction( sgPyQt.action( GUIcontext.SET_VALUE_ID ) )
375 popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
379 # several objects are selected
380 if len( selected ) == 1:
381 if GUIcontext.MODULE_ID in selected:
383 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
384 ## elif GUIcontext.OBJECT_ID in selected:
385 ## # menu for list of objects
386 ## popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
392 # called when GUI action is activated
393 # action ID is passed as parameter
394 def OnGUIEvent( commandID ):
395 if verbose() : print "GENERICSOLVERGUI.OnGUIEvent(): command = %d" % commandID
396 if dict_command.has_key( commandID ):
398 dict_command[commandID]()
400 traceback.print_exc()
402 if verbose() : print "The command is not implemented: %d" % commandID
405 # called when module's preferences are changed
406 # preference's resources section and setting name are passed as parameters
407 def preferenceChanged( section, setting ):
408 if verbose() : print "GENERICSOLVERGUI.preferenceChanged(): %s / %s" % ( section, setting )
411 # called when active view is changed
412 # view ID is passed as parameter
413 def activeViewChanged( viewID ):
414 if verbose() : print "GENERICSOLVERGUI.activeViewChanged(): %d" % viewID
417 # called when active view is cloned
418 # cloned view ID is passed as parameter
419 def viewCloned( viewID ):
420 if verbose() : print "GENERICSOLVERGUI.viewCloned(): %d" % viewID
423 # called when active view is viewClosed
424 # view ID is passed as parameter
425 def viewClosed( viewID ):
426 if verbose() : print "GENERICSOLVERGUI.viewClosed(): %d" % viewID
429 ################################################
430 # GUI actions implementation
431 ################################################
434 # 'SOLVER' dialog box
436 ##class MyDialog( QDialog ):
438 ## def __init__( self, parent = None, modal = 0):
439 ## QDialog.__init__( self, parent )
440 ## self.setObjectName( "MyDialog" )
441 ## self.setModal( modal )
442 ## self.setWindowTitle( "SOLVER!" )
443 ## vb = QVBoxLayout( self )
446 ## hb0 = QHBoxLayout( self )
447 ## label = QLabel( "Prenom: ", self )
448 ## hb0.addWidget( label )
449 ## self.entry = QLineEdit( self )
450 ## self.entry.setMinimumWidth( 200 )
451 ## hb0.addWidget( self.entry )
452 ## vb.addLayout( hb0 )
454 ## hb1 = QHBoxLayout( self )
455 ## bOk = QPushButton( "&OK", self )
456 ## self.connect( bOk, SIGNAL( 'clicked()' ), self, SLOT( 'accept()' ) )
457 ## hb1.addWidget( bOk )
459 ## hb1.addStretch( 10 )
461 ## bCancel = QPushButton( "&Cancel", self )
462 ## self.connect( bCancel, SIGNAL( 'clicked()' ), self, SLOT( 'close()' ) )
463 ## hb1.addWidget( bCancel )
465 ## vb.addLayout( hb1 )
469 ## def accept( self ):
470 ## name = str( self.entry.text() )
472 ## inPoint = [1, 2, 3]
474 ## print "GENERICSOLVERGUI.accept (1): inPoint = ", inPoint
475 ## print "GENERICSOLVERGUI.accept (1): outPoint = ", outPoint
476 ## (ok,outPoint) = getEngine().Exec( inPoint, outPoint )
477 ## QMessageBox.information( self, 'Info', "Exec() method returned %d" % ok )
478 ## print "GENERICSOLVERGUI.accept (2): inPoint = ", inPoint
479 ## print "GENERICSOLVERGUI.accept (2): outPoint = ", outPoint
482 ## QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
488 def addObjectInStudy( builder, father, objname, objid ):
489 obj = getSubSObjectByName( father, objname )
491 obj = builder.NewObject( father )
492 attr = builder.FindOrCreateAttribute( obj, "AttributeName" )
493 attr.SetValue( objname )
494 attr = builder.FindOrCreateAttribute( obj, "AttributeLocalID" )
495 attr.SetValue( objid )
498 def setValueToVariable( builder, varobj, value ):
499 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
501 if (objid == GUIcontext.VARIABLE_ID):
502 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
503 attr.SetValue( value )
505 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
506 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
509 def getValueOfVariable( builder, varobj ):
510 attr = builder.FindOrCreateAttribute( varobj, "AttributeLocalID" )
512 if (objid == GUIcontext.VARIABLE_ID):
513 attr = builder.FindOrCreateAttribute( varobj, "AttributeReal" )
516 attr = builder.FindOrCreateAttribute( varobj, "AttributeName" )
517 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "Object '%s' isn't a variable. Can't set value." % attr.Value() )
520 def getSubSObjectByName( sobjFather, childName ):
522 iter = study.NewChildIterator( sobjFather )
523 #builder = study.NewBuilder()
526 if sobj.GetName() == childName:
533 # Create a deterministic case
536 print "GENERICSOLVERGUI.CreateCase : enter"
537 default_case_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_case_name", GUIcontext.DEFAULT_CASE_NAME ).trimmed() )
539 if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
540 # request object name from the user
541 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
547 name = str( name.trimmed() )
548 elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
549 # generate object name
552 name = "%s %d" % ( default_case_name, __id__ )
554 name = default_case_name
558 # generate object name
561 name = "%s %d" % ( default_case_name, __id__ )
565 builder = study.NewBuilder()
566 father = findOrCreateComponent()
567 case = addObjectInStudy( builder, father, name, GUIcontext.CASE_ID )
568 varE = addObjectInStudy( builder, case, "E", GUIcontext.VARIABLE_ID )
569 setValueToVariable( builder, varE, 210.e9 )
570 varF = addObjectInStudy( builder, case, "F", GUIcontext.VARIABLE_ID )
571 setValueToVariable( builder, varF, 1000. )
572 varL = addObjectInStudy( builder, case, "L", GUIcontext.VARIABLE_ID )
573 setValueToVariable( builder, varL, 1.5 )
574 varI = addObjectInStudy( builder, case, "I", GUIcontext.VARIABLE_ID )
575 setValueToVariable( builder, varI, 2.e-6 )
576 sg.updateObjBrowser( True )
577 print "GENERICSOLVERGUI.CreateCase : exit"
581 # Get the selected deterministic case
583 def GetSelectedCase():
584 entry = sg.getSelected( 0 )
587 sobj = study.FindObjectID( entry )
589 test, attr = sobj.FindAttribute( "AttributeLocalID" )
590 print "GENERICSOLVERGUI.GetSelectedCase : test=%d attr=%d" % (test,attr.Value())
591 if attr.Value() == GUIcontext.CASE_ID: # This is a case entry
592 if hasChildren( sobj ):
595 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no child for case"
598 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! not a case"
601 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! selected object not found in study"
604 print "GENERICSOLVERGUI.GetSelectedCase : ERROR! no selection"
608 # Retrieve data from selected case
610 def GetDataFromCase( caseEntry ):
613 case = study.FindObjectID( caseEntry )
614 builder = study.NewBuilder()
615 # Get the values of the variables and make them a list
616 for name in ("E", "F", "L", "I"):
617 var = getSubSObjectByName( case, name )
619 print "GENERICSOLVERGUI.GetDataFromCase : ERROR! no variable '%s'" % name
621 theCase.append( getValueOfVariable( builder, var ) )
625 # Add some variable to the case
627 def AddDataToCase( caseEntry, varName, varValue ):
629 case = study.FindObjectID( caseEntry )
630 builder = study.NewBuilder()
631 var = addObjectInStudy( builder, case, varName, GUIcontext.VARIABLE_ID )
632 setValueToVariable( builder, var, varValue )
633 sg.updateObjBrowser( True )
640 case = GetSelectedCase()
641 getEngine().Init( getStudyId(), case, "" )
643 inPoint = GetDataFromCase( case )[:2]
644 print "GENERICSOLVERGUI.RunSOLVER (1): inPoint = ", inPoint
645 (ok, outPoint) = getEngine().Exec(inPoint)
646 print "GENERICSOLVERGUI.RunSOLVER (2): inPoint = ", inPoint
647 print "GENERICSOLVERGUI.RunSOLVER (2): outPoint = ", outPoint
648 AddDataToCase( case, "Deviation", outPoint[0] )
650 getEngine().Finalize()
657 ##def CreateObject():
658 ## default_name = str( sgPyQt.stringSetting( "GENERICSOLVER", "def_obj_name", GUIcontext.DEFAULT_NAME ).trimmed() )
660 ## if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
661 ## # request object name from the user
662 ## name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
664 ## "Enter object name:",
668 ## name = str( name.trimmed() )
669 ## elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
670 ## # generate object name
672 ## __id__ = __id__ + 1
673 ## name = "%s %d" % ( default_name, __id__ )
675 ## name = default_name
679 ## # generate object name
681 ## __id__ = __id__ + 1
682 ## name = "%s %d" % ( default_name, __id__ )
684 ## if not name: return
685 ## study = getStudy()
686 ## builder = study.NewBuilder()
687 ## father = findOrCreateComponent()
688 ## obj = addObjectInStudy( builder, father, name, GUIcontext.OBJECT_ID )
689 ## sg.updateObjBrowser( True )
697 father = study.FindComponent( GUIcontext.MODULE_NAME )
699 iter = study.NewChildIterator( father )
700 builder = study.NewBuilder()
704 builder.RemoveObjectWithChildren( sobj )
706 sg.updateObjBrowser( True )
715 entry = sg.getSelected( 0 )
717 sobj = study.FindObjectID( entry )
719 test, attr = sobj.FindAttribute( "AttributeName" )
721 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
728 # Delete selected object(s)
732 builder = study.NewBuilder()
733 if sg.SelectedCount() <= 0: return
734 for i in range( sg.SelectedCount() ):
735 entry = sg.getSelected( i )
737 sobj = study.FindObjectID( entry )
739 builder.RemoveObject( sobj )
743 sg.updateObjBrowser( True )
747 # Rename selected object
751 builder = study.NewBuilder()
752 entry = sg.getSelected( 0 )
754 sobj = study.FindObjectID( entry )
756 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
758 "Enter object name:",
761 name = str( name.trimmed() )
762 if not ok or not name: return
763 attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
764 attr.SetValue( name )
765 sg.updateObjBrowser( True )
771 # Set value to variable
775 builder = study.NewBuilder()
776 entry = sg.getSelected( 0 )
778 sobj = study.FindObjectID( entry )
780 name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
784 str(getValueOfVariable( builder, sobj)) )
785 value = float( name.trimmed() )
786 if not ok or not value: return
787 setValueToVariable( builder, sobj, value )
788 sg.updateObjBrowser( True )
794 # Commands dictionary
797 GUIcontext.SOLVER_ID : RunSOLVER,
798 GUIcontext.CREATE_CASE_ID : CreateCase,
799 ## GUIcontext.CREATE_OBJECT_ID : CreateObject,
800 GUIcontext.DELETE_ALL_ID : DeleteAll,
801 GUIcontext.SHOW_ME_ID : ShowMe,
802 GUIcontext.DELETE_ME_ID : Delete,
803 GUIcontext.RENAME_ME_ID : Rename,
804 GUIcontext.SET_VALUE_ID : SetValue,