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