Salome HOME
Switch DEV version marker to 1
[samples/atomgen.git] / src / ATOMGENGUI / ATOMGENGUI.py
1 # Copyright (C) 2007-2014  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, or (at your option) any later version.
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 __CMD_RUN_ALGO1__  = 4010
42
43 # study data
44 __study_data_map__ = {}
45
46 ################################################
47 # Init GUI wrappers
48
49 # get SALOME PyQt interface
50 import SalomePyQt
51 sgPyQt = SalomePyQt.SalomePyQt()
52
53 # get SALOME Swig interface
54 import libSALOME_Swig
55 sg = libSALOME_Swig.SALOMEGUI_Swig()
56
57 ################################################
58 # Global intializations
59
60 # init ORB
61 orb = CORBA.ORB_init( [''], CORBA.ORB_ID )
62
63 # create naming service instance
64 naming_service = SALOME_NamingServicePy_i( orb )
65
66 # create life cycle CORBA instance
67 lcc = LifeCycleCORBA( orb )
68
69 # get study manager
70 obj = naming_service.Resolve( '/myStudyManager' )
71 studyManager = obj._narrow( SALOMEDS.StudyManager )
72
73 ################################################
74 # Internal methods
75
76 def tr( s ):
77     """
78     Translate the message
79     """
80     return qApp.translate( "ATOMGENGUI", s )
81
82 def processException( e ):
83     """
84     Prints exception info
85     """
86     print "Exception has been caught:", e
87     pass
88
89 def warning( message, title = None ):
90     """
91     Show Warning message box
92     """
93     if not title: title = tr( "WARNING" )
94     QMessageBox.warning( sgPyQt.getDesktop(), title, message )
95     pass
96
97 # --- get ATOMGEN engine ---
98 engine = None
99 def _getEngine():
100     """
101     Gets an engine
102     """
103     global engine
104     if not engine:
105         engine = lcc.FindOrLoadComponent( "FactoryServerPy", __MODULE_NAME__ )
106     return engine
107
108 # --- get active study ---
109 def _getStudy():
110     """
111     Gets actuve study
112     """
113     studyId = sgPyQt.getStudyId()
114     study = studyManager.GetStudyByID( studyId )
115     return study
116
117 myStudy = None
118
119 ################################################
120 # Call back GUI methods
121
122
123 def initialize():
124     """
125     This method is called when GUI module is being created
126     and initialized.
127     Creates menus, toolbars and performs other internal
128     initialization
129     """
130     print "ATOMGENGUI::initialize"
131     global __study_data_map__
132     # get study id
133     studyId = sgPyQt.getStudyId()
134     if not __study_data_map__.has_key( studyId ):
135         __study_data_map__[ studyId ] = {}
136     # get selection object
137     selection = sgPyQt.getSelection()
138     selection.ClearIObjects()
139     __study_data_map__[ studyId ][ "selection" ] = selection
140     print "ATOMGENGUI::initialize done"
141     pass
142
143 def windows():
144     """
145     This method is called when GUI module is being created
146     and initialized.
147     Should return a map of the SALOME dockable windows id's
148     needed to be opened when module is activated.
149     """
150     print "ATOMGENGUI::windows"
151     winMap = {}
152     winMap[ SalomePyQt.WT_ObjectBrowser ] = Qt.LeftDockWidgetArea
153     winMap[ SalomePyQt.WT_PyConsole ]     = Qt.BottomDockWidgetArea
154     return winMap
155
156 def views():
157     """
158     This method is called when GUI module is being created
159     and initialized.
160     Should return a list of the SALOME view window types
161     needed to be opened when module is activated.
162     """
163     print "ATOMGENGUI::views"
164     return None
165
166 def activate():
167     """
168     This method is called when GUI module is being activated.
169     """
170     print "ATOMGENGUI::activate"
171     # set current study
172     global myStudy
173     global __study_data_map__
174     myStudy = _getStudy()
175     _getEngine().setCurrentStudy( myStudy )
176     studyId = myStudy._get_StudyId()
177
178     # create actions
179     __study_data_map__[ studyId ][ "actions" ] = {}
180     a = sgPyQt.createAction( __CMD_IMPORT_XML__,
181                              tr( "MEN_IMPORT_XML" ),
182                              tr( "TOP_IMPORT_XML" ),
183                              tr( "STB_IMPORT_XML" ) )
184     __study_data_map__[ studyId ][ "actions" ][ __CMD_IMPORT_XML__ ] = a
185     a = sgPyQt.createAction( __CMD_EXPORT_XML__,
186                              tr( "MEN_EXPORT_XML" ),
187                              tr( "TOP_EXPORT_XML" ),
188                              tr( "STB_EXPORT_XML" ) )
189     __study_data_map__[ studyId ][ "actions" ][ __CMD_EXPORT_XML__ ] = a
190
191     # create menus
192     fileMnu = sgPyQt.createMenu( QApplication.translate( "ATOMGENGUI", "MEN_FILE" ), -1, -1 )
193     sgPyQt.createMenu( sgPyQt.createSeparator(), fileMnu, -1, 20 )
194     sgPyQt.createMenu( __CMD_IMPORT_XML__, fileMnu, 20 )
195     sgPyQt.createMenu( __CMD_EXPORT_XML__, fileMnu, 20 )
196     sgPyQt.createMenu( sgPyQt.createSeparator(), fileMnu, -1, 20 )
197
198     # connect selection
199     selection = __study_data_map__[ studyId ][ "selection" ]
200     selection.ClearIObjects()
201     QObject.connect( selection, SIGNAL( "currentSelectionChanged()" ), selectionChanged )
202     global myRunDlg
203     if myRunDlg:
204         myRunDlg.close()
205         myRunDlg = None
206     return True
207
208 def deactivate():
209     """
210     This method is called when GUI module is being deactivated.
211     """
212     print "ATOMGENGUI::deactivate"
213     # connect selection
214     global myStudy
215     studyId = myStudy._get_StudyId()
216     selection = __study_data_map__[ studyId ][ "selection" ]
217     selection.ClearIObjects()
218     QObject.disconnect( selection, SIGNAL( "currentSelectionChanged()" ), selectionChanged )
219     global myRunDlg
220     if myRunDlg:
221         myRunDlg.close()
222         myRunDlg = None
223     myStudy = None
224     pass
225
226 def activeStudyChanged( studyId ):
227     """
228     This method is called when active study is chaghed
229     (user switches between studies desktops).
230     <studyId> is an id of study being activated.
231     """
232     print "ATOMGENGUI::activeStudyChanged: study Id =", studyId
233     global myStudy
234     if myStudy and myStudy._get_StudyId() == studyId:
235         return
236     global myRunDlg
237     if myRunDlg:
238         myRunDlg.close()
239         myRunDlg = None
240     pass
241
242 def createPopupMenu( popup, context ):
243     """
244     This method is called when popup menu is requested
245     by the user.
246     Should analyze the selection and fill in the popup menu
247     with the corresponding actions
248     """
249     print "ATOMGENGUI::createPopupMenu: popup =", popup, "; context =", context
250     selected = selectedItems()
251     isOk = False
252     for entry in selected:
253         sobject = myStudy.FindObjectID( entry )
254         if sobject and sobject.GetObject() and sobject.GetObject()._narrow( ATOMGEN_ORB.Molecule ):
255             isOk = True
256             break
257         pass
258     a = sgPyQt.action( __CMD_RUN_ALGO__ )
259     if isOk and a and context == "ObjectBrowser":
260         popup.addAction(a)
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 from rundlg_ui import Ui_RunDlg
283
284 class RunDlg(QDialog, 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 len(_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     __CMD_RUN_ALGO1__  : onRunAlgo,
443     }