]> SALOME platform Git repositories - samples/atomgen.git/blob - src/ATOMGENGUI/ATOMGENGUI.py
Salome HOME
Example of a python component from Salome tutorial
[samples/atomgen.git] / src / ATOMGENGUI / ATOMGENGUI.py
1 #  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 #  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 #  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
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.
10 #
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.
15 #
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
19 #
20 #  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21
22 from PyQt4.QtGui import *
23 from PyQt4.QtCore import *
24
25 from omniORB import CORBA
26 from SALOME_NamingServicePy import *
27 from LifeCycleCORBA import *
28 import SALOMEDS
29 import SALOMEDS_Attributes_idl
30 import ATOMGEN_ORB
31
32 ################################################
33 # Global definitions
34 #
35
36 # module name
37 __MODULE_NAME__ = "ATOMGEN"
38
39 # action IDs
40 __CMD_IMPORT_XML__ = 4000
41 __CMD_EXPORT_XML__ = 4001
42 __CMD_RUN_ALGO__   = 4002
43
44 # study data
45 __study_data_map__ = {}
46
47 ################################################
48 # Init GUI wrappers
49
50 # get SALOME PyQt interface
51 import SalomePyQt
52 sgPyQt = SalomePyQt.SalomePyQt()
53
54 # get SALOME Swig interface
55 import libSALOME_Swig
56 sg = libSALOME_Swig.SALOMEGUI_Swig()
57
58 ################################################
59 # Global intializations
60
61 # init ORB
62 orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
63
64 # create naming service instance
65 naming_service = SALOME_NamingServicePy_i( orb )
66
67 # create life cycle CORBA instance
68 lcc = LifeCycleCORBA( orb )
69
70 # get study manager
71 obj = naming_service.Resolve( '/myStudyManager' )
72 studyManager = obj._narrow( SALOMEDS.StudyManager )
73
74 ################################################
75 # Internal methods
76
77 def tr( s ):
78     """
79     Translate the message
80     """
81     return qApp.translate( "ATOMGENGUI", s )
82
83 def processException( e ):
84     """
85     Prints exception info
86     """
87     print "Exception has been caught:", e
88     pass
89
90 def warning( message, title = None ):
91     """
92     Show Warning message box
93     """
94     if not title: title = tr( "WARNING" )
95     QMessageBox.warning( sgPyQt.getDesktop(), title, message )
96     pass
97
98 # --- get ATOMGEN engine ---
99 engine = None
100 def _getEngine():
101     """
102     Gets an engine
103     """
104     global engine
105     if not engine:
106         engine = lcc.FindOrLoadComponent( "FactoryServerPy", __MODULE_NAME__ )
107     return engine
108
109 # --- get active study ---
110 def _getStudy():
111     """
112     Gets actuve study
113     """
114     studyId = sgPyQt.getStudyId()
115     study = studyManager.GetStudyByID( studyId )
116     return study
117
118 myStudy = None
119
120 ################################################
121 # Call back GUI methods
122
123
124 def initialize():
125     """
126     This method is called when GUI module is being created
127     and initialized.
128     Creates menus, toolbars and performs other internal
129     initialization
130     """
131     print "ATOMGENGUI::initialize"
132     global __study_data_map__
133     # get study id
134     studyId = sgPyQt.getStudyId()
135     if not __study_data_map__.has_key( studyId ):
136         __study_data_map__[ studyId ] = {}
137     # get selection object
138     selection = sgPyQt.getSelection()
139     selection.ClearIObjects()
140     __study_data_map__[ studyId ][ "selection" ] = selection
141     print "ATOMGENGUI::initialize done"
142     pass
143
144 def windows():
145     """
146     This method is called when GUI module is being created
147     and initialized.
148     Should return a map of the SALOME dockable windows id's
149     needed to be opened when module is activated.
150     """
151     print "ATOMGENGUI::windows"
152     winMap = {}
153     winMap[ SalomePyQt.WT_ObjectBrowser ] = Qt.LeftDockWidgetArea
154     winMap[ SalomePyQt.WT_PyConsole ]     = Qt.BottomDockWidgetArea
155     return winMap
156
157 def views():
158     """
159     This method is called when GUI module is being created
160     and initialized.
161     Should return a list of the SALOME view window types
162     needed to be opened when module is activated.
163     """
164     print "ATOMGENGUI::views"
165     return None
166
167 def activate():
168     """
169     This method is called when GUI module is being activated.
170     """
171     print "ATOMGENGUI::activate"
172     # set current study
173     global myStudy
174     global __study_data_map__
175     myStudy = _getStudy()
176     _getEngine().setCurrentStudy( myStudy )
177     studyId = myStudy._get_StudyId()
178
179     # create actions
180     __study_data_map__[ studyId ][ "actions" ] = {}
181     a = sgPyQt.createAction( __CMD_IMPORT_XML__,
182                              tr( "MEN_IMPORT_XML" ),
183                              tr( "TOP_IMPORT_XML" ),
184                              tr( "STB_IMPORT_XML" ) )
185     __study_data_map__[ studyId ][ "actions" ][ __CMD_IMPORT_XML__ ] = a
186     a = sgPyQt.createAction( __CMD_EXPORT_XML__,
187                              tr( "MEN_EXPORT_XML" ),
188                              tr( "TOP_EXPORT_XML" ),
189                              tr( "STB_EXPORT_XML" ) )
190     __study_data_map__[ studyId ][ "actions" ][ __CMD_EXPORT_XML__ ] = a
191
192     # create menus
193     fileMnu = sgPyQt.createMenu( QApplication.translate( "ATOMGENGUI", "MEN_FILE" ), -1, -1 )
194     sgPyQt.createMenu( sgPyQt.createSeparator(), fileMnu, -1, 20 )
195     sgPyQt.createMenu( __CMD_IMPORT_XML__, fileMnu, 20 )
196     sgPyQt.createMenu( __CMD_EXPORT_XML__, fileMnu, 20 )
197     sgPyQt.createMenu( sgPyQt.createSeparator(), fileMnu, -1, 20 )
198
199     # connect selection
200     selection = __study_data_map__[ studyId ][ "selection" ]
201     selection.ClearIObjects()
202     QObject.connect( selection, SIGNAL( "currentSelectionChanged()" ), selectionChanged )
203     global myRunDlg
204     if myRunDlg:
205         myRunDlg.close()
206         myRunDlg = None
207     return True
208
209 def deactivate():
210     """
211     This method is called when GUI module is being deactivated.
212     """
213     print "ATOMGENGUI::deactivate"
214     # connect selection
215     global myStudy
216     studyId = myStudy._get_StudyId()
217     selection = __study_data_map__[ studyId ][ "selection" ]
218     selection.ClearIObjects()
219     QObject.disconnect( selection, SIGNAL( "currentSelectionChanged()" ), selectionChanged )
220     global myRunDlg
221     if myRunDlg:
222         myRunDlg.close()
223         myRunDlg = None
224     myStudy = None
225     pass
226
227 def activeStudyChanged( studyId ):
228     """
229     This method is called when active study is chaghed
230     (user switches between studies desktops).
231     <studyId> is an id of study being activated.
232     """
233     print "ATOMGENGUI::activeStudyChanged: study Id =", studyId
234     global myStudy
235     if myStudy and myStudy._get_StudyId() == studyId:
236         return
237     global myRunDlg
238     if myRunDlg:
239         myRunDlg.close()
240         myRunDlg = None
241     pass
242
243 def createPopupMenu( popup, context ):
244     """
245     This method is called when popup menu is requested
246     by the user.
247     Should analyze the selection and fill in the popup menu
248     with the corresponding actions
249     """
250     print "ATOMGENGUI::createPopupMenu: popup =", popup, "; context =", context
251     selected = selectedItems()
252     isOk = False
253     for entry in selected:
254         sobject = myStudy.FindObjectID( entry )
255         if sobject and sobject.GetObject() and sobject.GetObject()._narrow( ATOMGEN_ORB.Molecule ):
256             isOk = True
257             break
258         pass
259     a = sgPyQt.action( __CMD_RUN_ALGO__ )
260     if isOk and a and context == "ObjectBrowser":
261         a.addTo( popup )
262     pass
263
264 def OnGUIEvent( commandId ):
265     """
266     This method is called when user activates some GUI action
267     <commandId> is an ID of the GUI action.
268     """
269     print "ATOMGENGUI::OnGUIEvent: commandId =", commandId
270     if dict_command.has_key( commandId ):
271         try:
272             dict_command[ commandId ]()
273         except Exception, e:
274             processException( e )
275     else:
276        print "ATOMGENGUI::OnGUIEvent: Action is not implemented: ", commandId
277     pass
278
279 ################################################
280 # GUI actions implementation
281
282 import ui_rundlg
283
284 class RunDlg(QDialog, ui_rundlg.Ui_RunDlg):
285     """
286     Run Algo simple dialog box
287     """
288     def __init__(self):
289         """
290         Constructor
291         """
292         QDialog.__init__(self, sgPyQt.getDesktop())
293         self.setupUi(self)
294         self.onCheckAll()
295         self.selected = []
296         self.selectionChanged()
297         pass
298         
299     def onCheckAll(self):
300         """
301         Called when user switches <Process all> check box
302         """
303         self.acLab.setEnabled( not self.allCheck.isChecked() )
304         self.acName.setEnabled( not self.allCheck.isChecked() )
305
306         selection = __study_data_map__[ myStudy._get_StudyId() ][ "selection" ]
307         if not self.allCheck.isChecked():
308             QObject.connect( selection, SIGNAL( "currentSelectionChanged()" ), self.selectionChanged )
309         else:
310             QObject.disconnect( selection, SIGNAL( "currentSelectionChanged()" ), self.selectionChanged )
311         pass
312
313     def selectionChanged(self):
314         """
315         Called when selection is changed
316         """
317         self.selected = []
318         selected = selectedItems()
319         for entry in selected:
320             sobject = myStudy.FindObjectID(entry)
321             if sobject:
322                 obj = sobject.GetObject()
323                 if obj and obj._narrow( ATOMGEN_ORB.Molecule ):
324                     self.selected.append( obj._narrow( ATOMGEN_ORB.Molecule ) )
325         if len( self.selected ) == 1:
326             self.acName.setText( self.selected[0].getName() )
327         elif len( self.selected ) > 1:
328             self.acName.setText(" %d objects selected"%len( self.selected ) )
329         else:
330             self.acName.setText( "" )
331         pass
332     
333     def run(self):
334         """
335         Starts algo
336         """
337         data = [] # all data to be processed
338         if not self.allCheck.isChecked():
339             data = self.selected
340         else:
341             component = myStudy.FindComponent( "ATOMGEN" )
342             if not component: return
343             iter = myStudy.NewChildIterator( component )
344             while iter.More():
345                 sobject = iter.Value()
346                 if sobject and sobject.GetObject() and sobject.GetObject()._narrow ( ATOMGEN_ORB.Molecule ):
347                     data.append( sobject.GetObject()._narrow( ATOMGEN_ORB.Molecule ) )
348                 iter.Next()
349             pass
350         if not len( data ): return
351         if not _getEngine().processData( data ):
352             warning( "ALGO_ERROR" )
353         else:
354             sgPyQt.updateObjBrowser()
355         pass
356
357     def close(self):
358         """
359         Closes dialog box
360         """
361         global myRunDlg
362         myRunDlg = None
363         QDialog.close(self)
364         pass
365         
366 myRunDlg = None
367
368 def selectedItems():
369     """
370     Gets list of entries of selected objects
371     """
372     nbSel = sg.SelectedCount()
373     selected = []
374     for i in range(nbSel):
375         selected.append(sg.getSelected(i))
376     return selected
377
378 def selectionChanged():
379     """
380     Global selection changed slot
381     """
382     selected = selectedItems()
383     print "--> Selected objects: %d"%len(selected)
384     pass
385
386 def onImportXml():
387     """
388     Import XML file action slot
389     """
390     print "--> onImportXml() is started"
391     filters = QStringList()
392     filters.append( tr( "XML_FILES" ) )
393     fileName = sgPyQt.getFileName( sgPyQt.getDesktop(),
394                                    "",
395                                    filters,
396                                    tr( "IMPORT_XML" ),
397                                    True )
398     if not fileName.isEmpty():
399         if not _getEngine().importXmlFile( str( fileName ) ):
400             warning( "IMPORT_ERROR" )
401         else:
402             sgPyQt.updateObjBrowser()
403     print "--> onImportXml() is finished"
404     pass
405
406 def onExportXml():
407     """
408     Export XML file action slot
409     """
410     print "--> onExportXml() is started"
411     filters = QStringList()
412     filters.append( tr( "XML_FILES" ) )
413     fileName = sgPyQt.getFileName( sgPyQt.getDesktop(),
414                                    "",
415                                    filters,
416                                    tr( "EXPORT_XML" ),
417                                    False )
418     if not fileName.isEmpty():
419         if not _getEngine().exportXmlFile( str( fileName ) ):
420             warning( "EXPORT_ERROR" )
421     print "--> onExportXml() is finished"
422     pass
423
424 def onRunAlgo():
425     print "--> onRunAlgo() is started !!!"
426     global myRunDlg
427     if not myRunDlg:
428         myRunDlg = RunDlg()
429     myRunDlg.show()
430     myRunDlg.activateWindow()
431     myRunDlg.setFocus()
432     print "--> onRunAlgol() is finished"
433     pass
434
435 ################################################
436 # action-to-function map
437
438 dict_command = {
439     __CMD_IMPORT_XML__ : onImportXml,
440     __CMD_EXPORT_XML__ : onExportXml,
441     __CMD_RUN_ALGO__   : onRunAlgo,
442     }