Salome HOME
debug probleme de cast entier booleen: changement de comportement sur les comparaison...
[modules/hydrosolver.git] / src / HYDROGUI / HYDROSOLVERGUI.py
1 #  Copyright (C) 2012-2013 EDF
2 #
3 #  This file is part of SALOME HYDRO module.
4 #
5 #  SALOME HYDRO module is free software: you can redistribute it and/or modify
6 #  it under the terms of the GNU General Public License as published by
7 #  the Free Software Foundation, either version 3 of the License, or
8 #  (at your option) any later version.
9 #
10 #  SALOME HYDRO module is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #  GNU General Public License for more details.
14 #
15 #  You should have received a copy of the GNU General Public License
16 #  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
17
18 import sys
19 import os
20 import traceback
21 import logging
22
23 from PyQt5.QtWidgets import QMessageBox, QApplication, QDialog
24
25 import salome
26 import SALOME
27 import SalomePyQt
28 sgPyQt = SalomePyQt.SalomePyQt()
29 from salome.kernel.studyedit import getStudyEditor
30 from salome.kernel.logger import Logger
31 from salome.kernel import termcolor
32 logger = Logger("HYDROGUI", color = termcolor.BLUE)
33 #logger.setLevel(logging.ERROR)
34
35 import HYDROSOLVER_ORB
36
37 from salome.hydro.interpolz_gui import InterpolzDlg
38 from salome.hydro.assignStrickler_gui import assignStricklerDlg
39 from salome.hydro.gui_utils import HSGUIException, wait_cursor, \
40                                    get_and_check_selected_file_path
41 import salome.hydro.study as hydro_study
42 from salome.hydro.run_study.eficas.appli import EficasForRunStudyAppli
43 from salome.hydro.param_study.eficas.appli import EficasForParamStudyAppli
44 from salome.hydro.telma.eficas.appli import EficasForTelmaAppli
45 from salome.hydro.run_study.gui import create_case_study, \
46                                    run_selected_case_study, \
47                                    edit_selected_case_study, \
48                                    generate_job_for_selected_case_study
49 from eficasSalome import runEficas
50
51 from BndConditionsDialog import BoundaryConditionsDialog
52 from LiquidBoundariesDialog import LiquidBoundariesDialog
53 from BreachesDialog import BreachesDialog
54 from InitialConditionsDialog import InitialConditionsDialog
55
56 ################################################
57 # GUI context class
58 # Used to store actions, menus, toolbars, etc...
59 ################################################
60
61 class GUIcontext:
62   
63     # --- menus/toolbars/actions IDs
64     
65     HYDRO_MENU_ID = 90
66     CREATE_STUDY_ID = 951
67     EDIT_STUDY_ID = 952
68     RUN_STUDY_ID = 953
69     GEN_STUDY_BATCH_ID = 954
70
71     CREATE_TELMA_CAS_ID = 955
72     EDIT_TELMA_CAS_ID = 956
73
74     GENERATE_INTERPOLZ_PY_ID = 957
75     GENERATE_ASSIGNSTRICKLER_PY_ID = 958
76
77     # TODO Add create and edit ?
78     EDIT_BOUNDARY_CONDITIONS_FILE_ID = 959
79     EDIT_LIQUID_BOUNDARY_FILE_ID = 960
80     EDIT_BREACHES_FILE_ID = 961
81     EDIT_INITIAL_CONDITIONS_FILE_ID = 962
82
83     CREATE_PARAM_STUDY_ID = 963
84     EDIT_PARAM_STUDY_ID = 964
85     GEN_PARAM_STUDY_PYTHON_ID = 965
86     GEN_PARAM_STUDY_YACS_ID = 966
87
88     def __init__(self):
89         # create top-level menu
90         mid = sgPyQt.createMenu("Hydro", -1, GUIcontext.HYDRO_MENU_ID,
91                                 sgPyQt.defaultMenuGroup())
92         # create toolbar
93         tid = sgPyQt.createTool("Hydro")
94         # create actions and fill menu and toolbar with actions
95         act = sgPyQt.createAction(\
96                 GUIcontext.GENERATE_INTERPOLZ_PY_ID,
97                 "Generate interpolz.py",
98                 "Generate interpolz.py",
99                 "Generate interpolation script for altitudes",
100                 "generate_interpolz_py.png")
101         sgPyQt.createMenu(act, mid)
102         sgPyQt.createTool(act, tid)
103
104         act = sgPyQt.createAction(\
105                 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID,
106                 "Generate assignStrickler.py",
107                 "Generate assignStrickler.py",
108                 "Generate assignation script for bottom friction coefficients",
109                  "generate_interpolz_py.png" )
110         sgPyQt.createMenu( act, mid )
111         sgPyQt.createTool( act, tid )
112         
113         act = sgPyQt.createSeparator()
114
115         act = sgPyQt.createAction(\
116                 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID,
117                 "Edit boundary conditions file",
118                 "Edit boundary conditions file",
119                 "Create/edit the boundary conditions file for Telemac",
120                 "edit_boundary_conditions_file.png")
121         sgPyQt.createMenu(act, mid)
122         sgPyQt.createTool(act, tid)
123
124         act = sgPyQt.createAction(\
125                 GUIcontext.EDIT_LIQUID_BOUNDARY_FILE_ID,
126                 "Edit liquid boundary conditions file",
127                 "Edit liquid boundary conditions file",
128                 "Create/edit the liquid boundary conditions file for Telemac",
129                 "edit_liquid_boundary_conditions_file.png")
130         sgPyQt.createMenu(act, mid)
131         sgPyQt.createTool(act, tid)
132
133         act = sgPyQt.createAction(\
134                 GUIcontext.EDIT_BREACHES_FILE_ID,
135                 "Edit breaches file",
136                 "Edit breaches file",
137                 "Create/edit the breaches file for Telemac",
138                 "edit_breaches_file.png")
139         sgPyQt.createMenu(act, mid)
140         sgPyQt.createTool(act, tid)
141         
142         act = sgPyQt.createAction(\
143                 GUIcontext.EDIT_INITIAL_CONDITIONS_FILE_ID,
144                 "Edit initial conditions file",
145                 "Edit initial conditions file",
146                 "Create/edit the initial conditions file for Telemac",
147                 "edit_boundary_conditions_file.png" )
148         sgPyQt.createMenu( act, mid )
149         sgPyQt.createTool( act, tid )
150
151         act = sgPyQt.createAction(\
152                 GUIcontext.CREATE_TELMA_CAS_ID,
153                 "Edit cas file (English)",
154                 "Edit cas file (English)",
155                 "Create/edit act .cas file for Telemac (English)",
156                 "create_telma_cas.png")
157         sgPyQt.createMenu(act, mid)
158         sgPyQt.createTool(act, tid)
159
160         act = sgPyQt.createAction(\
161                 GUIcontext.CREATE_STUDY_ID,
162                 "Execute a steering file",
163                 "Execute a steering file",
164                 "Fill formular for a normal execution",
165                 "create_study.png")
166
167         sgPyQt.createMenu(act, mid)
168         sgPyQt.createTool(act, tid)
169
170         act = sgPyQt.createAction(\
171                 GUIcontext.CREATE_PARAM_STUDY_ID,
172                 "Create Parameter Study",
173                 "Create Parameter Study",
174                 "Create act new Parameter Study",
175                 "create_param_study.png")
176         sgPyQt.createMenu(act, mid)
177         sgPyQt.createTool(act, tid)
178
179         act = sgPyQt.createSeparator()
180
181         # the following action are used in context popup
182
183         sgPyQt.createAction(\
184                 GUIcontext.EDIT_PARAM_STUDY_ID,
185                 "Edit param study",
186                 "Edit param study",
187                 "Edit study using python launcher")
188         sgPyQt.createAction(\
189                 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID,
190                 "Generate Python script",
191                 "Generate Python script",
192                 "Generate act Python script from the eficas date")
193         sgPyQt.createAction(\
194                 GUIcontext.GEN_PARAM_STUDY_YACS_ID,
195                 "Generate YACS script",
196                 "Generate YACS script",
197                 "Generate act YACS script from the eficas date")
198
199         sgPyQt.createAction(\
200                 GUIcontext.RUN_STUDY_ID,
201                 "Compute study",
202                 "Compute study",
203                 "Compute study using python launcher")
204         sgPyQt.createAction(\
205                 GUIcontext.EDIT_STUDY_ID,
206                 "Edit study",
207                 "Edit study",
208                 "Edit the selected study")
209         sgPyQt.createAction(\
210                 GUIcontext.GEN_STUDY_BATCH_ID,
211                 "Generate batch job",
212                 "Generate batch job",
213                 "Generate a batch job to run the selected study")
214
215         sgPyQt.createAction(\
216                 GUIcontext.EDIT_TELMA_CAS_ID,
217                 "Edit Steering file",
218                 "Edit Steering file",
219                 "Edit a Telemac-Mascaret steering file")
220
221
222 ################################################
223 # Global variables
224 ################################################
225
226 # study-to-context map
227 __study2context__ = {}
228 # current context
229 __current_context__ = None
230 # object counter
231 __objectid__ = 0
232
233 ################################################
234 # Internal methods
235 ################################################
236
237 ###
238 # get active study ID
239 ###
240 #def _getStudyId():
241     #return sgPyQt.getStudyId()
242
243 ###
244 # get active study
245 ###
246 #def _getStudy():
247     #studyId = _getStudyId()
248     #study = getStudyManager().GetStudyByID(studyId)
249     #return study
250
251 ###
252 # returns True if object has children
253 ###
254 def _hasChildren(sobj):
255     if sobj:
256         study = salome.myStudy
257         iter  = study.NewChildIterator(sobj)
258         while iter.More():
259             name = iter.Value().GetName()
260             if name:
261                 return True
262             iter.Next()
263             pass
264         pass
265     return False
266
267 ###
268 # get current GUI context
269 ###
270 def _getContext():
271     global __current_context__
272     return __current_context__
273
274 ###
275 # set and return current GUI context
276 # study ID is passed as parameter
277 ###
278 def _setContext():
279     global __study2context__, __current_context__
280     #if studyID not in __study2context__:
281         #__study2context__[studyID] = GUIcontext()
282         #pass
283     #__current_context__ = __study2context__[studyID]
284     __current_context__ = GUIcontext()
285     return __current_context__
286
287 ###
288 # increment object counter in the map
289 ###
290 def _incObjToMap(m, id):
291     if id not in m: m[id] = 0
292     m[id] += 1
293     pass
294
295 ################################################
296 # Callback functions
297 ################################################
298
299 # called when module is activated
300 # returns True if activating is successfull and False otherwise
301 def activate():
302     ctx = _setContext()
303     return True
304
305 # called when module is deactivated
306 def deactivate():
307     pass
308
309 # called when active study is changed
310 # active study ID is passed as parameter
311 def activeStudyChanged():
312     ctx = _setContext()
313     pass
314
315 # called when popup menu is invoked
316 # popup menu and menu context are passed as parameters
317 def createPopupMenu(popup, context):
318     ed = getStudyEditor()
319     _setContext()
320     if salome.sg.SelectedCount() == 1:
321         # one object is selected
322         sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
323         selectedType = ed.getTypeId(sobj)
324         if selectedType == hydro_study.TELMA_TYPE_ID:
325             popup.addAction(sgPyQt.action(GUIcontext.EDIT_TELMA_CAS_ID))
326         elif selectedType == hydro_study.PARAM_STUDY_TYPE_ID:
327             popup.addAction(sgPyQt.action(GUIcontext.EDIT_PARAM_STUDY_ID))
328             popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_PYTHON_ID))
329             popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_YACS_ID))
330         elif selectedType == hydro_study.STUDY_TYPE_ID:
331             popup.addAction(sgPyQt.action(GUIcontext.EDIT_STUDY_ID))
332             popup.addAction(sgPyQt.action(GUIcontext.RUN_STUDY_ID))
333             popup.addAction(sgPyQt.action(GUIcontext.GEN_STUDY_BATCH_ID))
334
335 # called when GUI action is activated
336 # action ID is passed as parameter
337 def OnGUIEvent(commandID):
338     try:
339         dict_command[commandID]()
340     except HSGUIException as exc:
341         QMessageBox.critical(sgPyQt.getDesktop(),
342                                    QApplication.translate("OnGUIEvent", "Error"),
343                                    str(exc))
344     except:
345         logger.exception("Unhandled exception caught in HYDROSOLVER GUI")
346         msg = QApplication.translate("OnGUIEvent",
347             "Unhandled error happened in HYDROSOLVER module. Please report a bug on "
348             '<a href="https://forge-pleiade.der.edf.fr/projects/salome-rex/issues">SALOME bugtracker</a>, '
349             'category "HYDROSOLVER", describing how you got there and including the following traceback:')
350         msgBox = QMessageBox(QMessageBox.Critical,
351                                    QApplication.translate("OnGUIEvent", "Error"),
352                                    msg,
353                                    parent=sgPyQt.getDesktop())
354         msgBox.setDetailedText(traceback.format_exc())
355         msgBox.exec_()
356
357 ################################################
358 # GUI actions implementation
359 ################################################
360
361 ###
362 # Open Eficas for a new parametric study
363 ###
364 def create_param_study():
365     EficasForParamStudyAppli()
366 ###
367 # Open Eficas to edit a new parametric study
368 ###
369 def edit_param_study():
370     EficasForParamStudyAppli(get_and_check_selected_file_path())
371
372 ###
373 # Generate a python script from the eficas file
374 ###
375 def generate_param_study_python():
376     try:
377         with wait_cursor:
378             ed = hydro_study.HydroStudyEditor()
379             sobj = get_and_check_selected_file_path()
380             ed.generate_study_script(sobj)
381     except SALOME.SALOME_Exception as exc:
382         salome.sg.updateObjBrowser()
383         msg = str(QApplication.translate("generate_telemac2d_python",
384                       "An error happened while trying to generate telemac2d Python script:"))
385         msg += "\n" + exc.details.text
386         raise HSGUIException(msg)
387
388 ###
389 # Generate a python script from the eficas file
390 ###
391 def generate_param_study_yacs():
392     try:
393         with wait_cursor:
394             ed = hydro_study.HydroStudyEditor()
395             sobj = get_and_check_selected_file_path()
396             ed.generate_study_yacs(sobj)
397     except SALOME.SALOME_Exception as exc:
398         salome.sg.updateObjBrowser()
399         msg = str(QApplication.translate("generate_telemac2d_yacs",
400                       "An error happened while trying to generate telemac2d Python script:"))
401         msg += "\n" + exc.details.text
402         raise HSGUIException(msg)
403
404 def open_schema_in_yacs():
405     ed = getStudyEditor()
406     sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
407     filename = sobj.GetComment()
408     if filename.endswith(".comm"):
409         filename = filename[:-5] + ".xml"
410     if not os.path.isfile(filename):
411         raise HSGUIException(QApplication.translate("open_schema_in_yacs",
412                                   "Schema file %1 does not exist").arg(filename))
413     yg = salome.ImportComponentGUI("YACS")
414     yg.loadSchema(filename)
415
416 ###
417 # Open dialog for boundary conditions edition
418 ###
419 def edit_boundary_conditions_file():
420     desktop = sgPyQt.getDesktop()
421     dlg = BoundaryConditionsDialog(desktop)
422     dlg.exec_()
423
424 ###
425 # Open dialog for liquid boundaries edition
426 ###
427 def edit_liquid_boundaries_file():
428     desktop = sgPyQt.getDesktop()
429     dlg = LiquidBoundariesDialog(desktop)
430     dlg.exec_()
431
432 ###
433 # Open dialog for breaches edition
434 ###
435 def edit_breaches_file():
436     desktop = sgPyQt.getDesktop()
437     dlg = BreachesDialog(desktop)
438     dlg.exec_()
439
440 ###
441 # Open dialog for initial conditions edition
442 ###
443 def edit_initial_conditions_file():
444     desktop = sgPyQt.getDesktop()
445     dlg = InitialConditionsDialog(desktop)
446     dlg.exec_()
447
448 ###
449 # Open dialog for liquid boundary conditions edition
450 ###
451 def edit_liquid_boundary_file():
452     # TODO: Implement gui
453     QMessageBox.warning(sgPyQt.getDesktop(),
454                         "",
455                         "Liquid boundary file handling not implemented yet")
456     return
457
458 ###
459 # Open dialog for breaches file edition
460 ###
461 def edit_breaches_file():
462     # TODO: Implement gui
463     QMessageBox.warning(sgPyQt.getDesktop(),
464                         "",
465                         "Breaches file handling not implemented yet")
466     return
467
468 ###
469 # Open dialog for interpolz.py script generation
470 ###
471 def generate_interpolz_py():
472     desktop = sgPyQt.getDesktop()
473     dlg = InterpolzDlg(desktop)
474     dlg.show()
475
476 ###
477 # Open dialog for assignStrickler.py script generation
478 ###
479 def generate_assignStrickler_py():
480     desktop = sgPyQt.getDesktop()
481     dlg = assignStricklerDlg(desktop)
482     dlg.show()
483
484 ###
485 # Open dialog for boundary conditions edition
486 ###
487 def generate_interpolks_py():
488     QMessageBox.warning(sgPyQt.getDesktop(),
489                         "",
490                         "Generation of interpolks.py not implemented yet")
491     return
492
493 ###
494 # Open dialog for creation of steering file
495 ###
496 def create_telma_cas():
497     EficasForTelmaAppli(code='TELEMAC', lang='en')
498
499 ###
500 # Open dialog for edition of steering file
501 ###
502 def edit_telma_cas():
503     # TODO: See how to detect module
504     EficasForTelmaAppli(fichier=get_and_check_selected_file_path(),
505                         code='TELEMAC', lang='en')
506
507 ###
508 # Commands dictionary
509 ###
510 dict_command = {
511     GUIcontext.CREATE_STUDY_ID: create_case_study,
512     GUIcontext.EDIT_STUDY_ID: edit_selected_case_study,
513     GUIcontext.RUN_STUDY_ID: run_selected_case_study,
514     GUIcontext.GEN_STUDY_BATCH_ID: generate_job_for_selected_case_study,
515     GUIcontext.CREATE_TELMA_CAS_ID: create_telma_cas,
516     GUIcontext.EDIT_TELMA_CAS_ID: edit_telma_cas,
517     GUIcontext.GENERATE_INTERPOLZ_PY_ID: generate_interpolz_py,
518     GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID: generate_assignStrickler_py,
519     GUIcontext.EDIT_LIQUID_BOUNDARY_FILE_ID: edit_liquid_boundary_file,
520     GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID: edit_boundary_conditions_file,
521     GUIcontext.EDIT_BREACHES_FILE_ID: edit_breaches_file,
522     GUIcontext.EDIT_INITIAL_CONDITIONS_FILE_ID: edit_initial_conditions_file,
523     GUIcontext.CREATE_PARAM_STUDY_ID: create_param_study,
524     GUIcontext.EDIT_PARAM_STUDY_ID: edit_param_study,
525     GUIcontext.GEN_PARAM_STUDY_PYTHON_ID: generate_param_study_python,
526     GUIcontext.GEN_PARAM_STUDY_YACS_ID: generate_param_study_yacs,
527     }