1 # Copyright (C) 2012-2013 EDF
3 # This file is part of SALOME HYDRO module.
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.
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.
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/>.
23 from PyQt5.QtWidgets import QMessageBox, QApplication, QDialog
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)
35 import HYDROSOLVER_ORB
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
51 from BndConditionsDialog import BoundaryConditionsDialog
52 from LiquidBoundariesDialog import LiquidBoundariesDialog
53 from BreachesDialog import BreachesDialog
54 from InitialConditionsDialog import InitialConditionsDialog
56 ################################################
58 # Used to store actions, menus, toolbars, etc...
59 ################################################
63 # --- menus/toolbars/actions IDs
69 GEN_STUDY_BATCH_ID = 954
71 CREATE_TELMA_CAS_ID = 955
72 EDIT_TELMA_CAS_ID = 956
74 GENERATE_INTERPOLZ_PY_ID = 957
75 GENERATE_ASSIGNSTRICKLER_PY_ID = 958
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
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
89 # create top-level menu
90 mid = sgPyQt.createMenu("Hydro", -1, GUIcontext.HYDRO_MENU_ID,
91 sgPyQt.defaultMenuGroup())
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)
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 )
113 act = sgPyQt.createSeparator()
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)
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)
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)
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 )
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)
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",
167 sgPyQt.createMenu(act, mid)
168 sgPyQt.createTool(act, tid)
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)
179 act = sgPyQt.createSeparator()
181 # the following action are used in context popup
183 sgPyQt.createAction(\
184 GUIcontext.EDIT_PARAM_STUDY_ID,
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")
199 sgPyQt.createAction(\
200 GUIcontext.RUN_STUDY_ID,
203 "Compute study using python launcher")
204 sgPyQt.createAction(\
205 GUIcontext.EDIT_STUDY_ID,
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")
215 sgPyQt.createAction(\
216 GUIcontext.EDIT_TELMA_CAS_ID,
217 "Edit Steering file",
218 "Edit Steering file",
219 "Edit a Telemac-Mascaret steering file")
222 ################################################
224 ################################################
226 # study-to-context map
227 __study2context__ = {}
229 __current_context__ = None
233 ################################################
235 ################################################
238 # get active study ID
241 return sgPyQt.getStudyId()
247 studyId = _getStudyId()
248 study = getStudyManager().GetStudyByID(studyId)
252 # returns True if object has children
254 def _hasChildren(sobj):
257 iter = study.NewChildIterator(sobj)
259 name = iter.Value().GetName()
268 # get current GUI context
271 global __current_context__
272 return __current_context__
275 # set and return current GUI context
276 # study ID is passed as parameter
278 def _setContext(studyID):
279 global __study2context__, __current_context__
280 if studyID not in __study2context__:
281 __study2context__[studyID] = GUIcontext()
283 __current_context__ = __study2context__[studyID]
284 return __current_context__
287 # increment object counter in the map
289 def _incObjToMap(m, id):
290 if id not in m: m[id] = 0
294 ################################################
296 ################################################
298 # called when module is activated
299 # returns True if activating is successfull and False otherwise
301 ctx = _setContext(_getStudyId())
304 # called when module is deactivated
308 # called when active study is changed
309 # active study ID is passed as parameter
310 def activeStudyChanged(studyID):
311 ctx = _setContext(_getStudyId())
314 # called when popup menu is invoked
315 # popup menu and menu context are passed as parameters
316 def createPopupMenu(popup, context):
317 ed = getStudyEditor()
318 _setContext(ed.studyId)
319 if salome.sg.SelectedCount() == 1:
320 # one object is selected
321 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
322 selectedType = ed.getTypeId(sobj)
323 if selectedType == hydro_study.TELMA_TYPE_ID:
324 popup.addAction(sgPyQt.action(GUIcontext.EDIT_TELMA_CAS_ID))
325 elif selectedType == hydro_study.PARAM_STUDY_TYPE_ID:
326 popup.addAction(sgPyQt.action(GUIcontext.EDIT_PARAM_STUDY_ID))
327 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_PYTHON_ID))
328 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_YACS_ID))
329 elif selectedType == hydro_study.STUDY_TYPE_ID:
330 popup.addAction(sgPyQt.action(GUIcontext.EDIT_STUDY_ID))
331 popup.addAction(sgPyQt.action(GUIcontext.RUN_STUDY_ID))
332 popup.addAction(sgPyQt.action(GUIcontext.GEN_STUDY_BATCH_ID))
334 # called when GUI action is activated
335 # action ID is passed as parameter
336 def OnGUIEvent(commandID):
338 dict_command[commandID]()
339 except HSGUIException as exc:
340 QMessageBox.critical(sgPyQt.getDesktop(),
341 QApplication.translate("OnGUIEvent", "Error"),
344 logger.exception("Unhandled exception caught in HYDROSOLVER GUI")
345 msg = QApplication.translate("OnGUIEvent",
346 "Unhandled error happened in HYDROSOLVER module. Please report a bug on "
347 '<a href="https://forge-pleiade.der.edf.fr/projects/salome-rex/issues">SALOME bugtracker</a>, '
348 'category "HYDROSOLVER", describing how you got there and including the following traceback:')
349 msgBox = QMessageBox(QMessageBox.Critical,
350 QApplication.translate("OnGUIEvent", "Error"),
352 parent=sgPyQt.getDesktop())
353 msgBox.setDetailedText(traceback.format_exc())
356 ################################################
357 # GUI actions implementation
358 ################################################
361 # Open Eficas for a new parametric study
363 def create_param_study():
364 EficasForParamStudyAppli()
366 # Open Eficas to edit a new parametric study
368 def edit_param_study():
369 EficasForParamStudyAppli(get_and_check_selected_file_path())
372 # Generate a python script from the eficas file
374 def generate_param_study_python():
377 ed = hydro_study.HydroStudyEditor()
378 sobj = get_and_check_selected_file_path()
379 ed.generate_study_script(sobj)
380 except SALOME.SALOME_Exception as exc:
381 salome.sg.updateObjBrowser(0)
382 msg = str(QApplication.translate("generate_telemac2d_python",
383 "An error happened while trying to generate telemac2d Python script:"))
384 msg += "\n" + exc.details.text
385 raise HSGUIException(msg)
388 # Generate a python script from the eficas file
390 def generate_param_study_yacs():
393 ed = hydro_study.HydroStudyEditor()
394 sobj = get_and_check_selected_file_path()
395 ed.generate_study_yacs(sobj)
396 except SALOME.SALOME_Exception as exc:
397 salome.sg.updateObjBrowser(0)
398 msg = str(QApplication.translate("generate_telemac2d_yacs",
399 "An error happened while trying to generate telemac2d Python script:"))
400 msg += "\n" + exc.details.text
401 raise HSGUIException(msg)
403 def open_schema_in_yacs():
404 ed = getStudyEditor()
405 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
406 filename = sobj.GetComment()
407 if filename.endswith(".comm"):
408 filename = filename[:-5] + ".xml"
409 if not os.path.isfile(filename):
410 raise HSGUIException(QApplication.translate("open_schema_in_yacs",
411 "Schema file %1 does not exist").arg(filename))
412 yg = salome.ImportComponentGUI("YACS")
413 yg.loadSchema(filename)
416 # Open dialog for boundary conditions edition
418 def edit_boundary_conditions_file():
419 desktop = sgPyQt.getDesktop()
420 dlg = BoundaryConditionsDialog(desktop)
424 # Open dialog for liquid boundaries edition
426 def edit_liquid_boundaries_file():
427 desktop = sgPyQt.getDesktop()
428 dlg = LiquidBoundariesDialog(desktop)
432 # Open dialog for breaches edition
434 def edit_breaches_file():
435 desktop = sgPyQt.getDesktop()
436 dlg = BreachesDialog(desktop)
440 # Open dialog for initial conditions edition
442 def edit_initial_conditions_file():
443 desktop = sgPyQt.getDesktop()
444 dlg = InitialConditionsDialog(desktop)
448 # Open dialog for liquid boundary conditions edition
450 def edit_liquid_boundary_file():
451 # TODO: Implement gui
452 QMessageBox.warning(sgPyQt.getDesktop(),
454 "Liquid boundary file handling not implemented yet")
458 # Open dialog for breaches file edition
460 def edit_breaches_file():
461 # TODO: Implement gui
462 QMessageBox.warning(sgPyQt.getDesktop(),
464 "Breaches file handling not implemented yet")
468 # Open dialog for interpolz.py script generation
470 def generate_interpolz_py():
471 desktop = sgPyQt.getDesktop()
472 dlg = InterpolzDlg(desktop)
476 # Open dialog for assignStrickler.py script generation
478 def generate_assignStrickler_py():
479 desktop = sgPyQt.getDesktop()
480 dlg = assignStricklerDlg(desktop)
484 # Open dialog for boundary conditions edition
486 def generate_interpolks_py():
487 QMessageBox.warning(sgPyQt.getDesktop(),
489 "Generation of interpolks.py not implemented yet")
493 # Open dialog for creation of steering file
495 def create_telma_cas():
496 EficasForTelmaAppli(code='TELEMAC', lang='en')
499 # Open dialog for edition of steering file
501 def edit_telma_cas():
502 # TODO: See how to detect module
503 EficasForTelmaAppli(fichier=get_and_check_selected_file_path(),
504 code='TELEMAC', lang='en')
507 # Commands dictionary
510 GUIcontext.CREATE_STUDY_ID: create_case_study,
511 GUIcontext.EDIT_STUDY_ID: edit_selected_case_study,
512 GUIcontext.RUN_STUDY_ID: run_selected_case_study,
513 GUIcontext.GEN_STUDY_BATCH_ID: generate_job_for_selected_case_study,
514 GUIcontext.CREATE_TELMA_CAS_ID: create_telma_cas,
515 GUIcontext.EDIT_TELMA_CAS_ID: edit_telma_cas,
516 GUIcontext.GENERATE_INTERPOLZ_PY_ID: generate_interpolz_py,
517 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID: generate_assignStrickler_py,
518 GUIcontext.EDIT_LIQUID_BOUNDARY_FILE_ID: edit_liquid_boundary_file,
519 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID: edit_boundary_conditions_file,
520 GUIcontext.EDIT_BREACHES_FILE_ID: edit_breaches_file,
521 GUIcontext.EDIT_INITIAL_CONDITIONS_FILE_ID: edit_initial_conditions_file,
522 GUIcontext.CREATE_PARAM_STUDY_ID: create_param_study,
523 GUIcontext.EDIT_PARAM_STUDY_ID: edit_param_study,
524 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID: generate_param_study_python,
525 GUIcontext.GEN_PARAM_STUDY_YACS_ID: generate_param_study_yacs,