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