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.changeCoordsDialog import changeCoordsDialog
40 from salome.hydro.gui_utils import HSGUIException, wait_cursor, \
41 get_and_check_selected_file_path
42 import salome.hydro.study as hydro_study
43 from salome.hydro.run_study.eficas.appli import EficasForRunStudyAppli
44 from salome.hydro.param_study.eficas.appli import EficasForParamStudyAppli
45 from salome.hydro.telma.eficas.appli import EficasForTelmaAppli
46 from salome.hydro.run_study.gui import create_case_study, \
47 run_selected_case_study, \
48 edit_selected_case_study, \
49 generate_job_for_selected_case_study
50 from eficasSalome import runEficas
52 from BndConditionsDialog import BoundaryConditionsDialog
53 from LiquidBoundariesDialog import LiquidBoundariesDialog
54 from BreachesDialog import BreachesDialog
55 from salome.hydro.initialFieldDialog import initialFieldDialog
57 ################################################
59 # Used to store actions, menus, toolbars, etc...
60 ################################################
64 # --- menus/toolbars/actions IDss
70 GEN_STUDY_BATCH_ID = 954
72 CREATE_TELMA_CAS_ID = 955
73 EDIT_TELMA_CAS_ID = 956
75 GENERATE_INTERPOLZ_PY_ID = 957
76 GENERATE_ASSIGNSTRICKLER_PY_ID = 958
78 # TODO Add create and edit ?
79 EDIT_BOUNDARY_CONDITIONS_FILE_ID = 959
80 EDIT_LIQUID_BOUNDARY_FILE_ID = 960
81 EDIT_BREACHES_FILE_ID = 961
82 EDIT_INITIAL_FIELD_FILE_ID = 962
84 CREATE_PARAM_STUDY_ID = 963
85 EDIT_PARAM_STUDY_ID = 964
86 GEN_PARAM_STUDY_PYTHON_ID = 965
87 GEN_PARAM_STUDY_YACS_ID = 966
89 CHANGECOORDS_PY_ID = 967
92 # create top-level menu
93 mid = sgPyQt.createMenu("Hydro", -1, GUIcontext.HYDRO_MENU_ID,
94 sgPyQt.defaultMenuGroup())
96 tid = sgPyQt.createTool("Hydro")
97 # create actions and fill menu and toolbar with actions
98 act = sgPyQt.createAction(\
99 GUIcontext.CHANGECOORDS_PY_ID,
100 "Change coordinates",
101 "Change coordinates",
102 "Change mesh coordinates",
103 "generate_interpolz_py.png")
104 sgPyQt.createMenu(act, mid)
105 sgPyQt.createTool(act, tid)
107 act = sgPyQt.createAction(\
108 GUIcontext.GENERATE_INTERPOLZ_PY_ID,
109 "Generate interpolz.py",
110 "Generate interpolz.py",
111 "Generate interpolation script for altitudes",
112 "generate_interpolz_py.png")
113 sgPyQt.createMenu(act, mid)
114 sgPyQt.createTool(act, tid)
116 act = sgPyQt.createAction(\
117 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID,
118 "Generate assignStrickler.py",
119 "Generate assignStrickler.py",
120 "Generate assignation script for bottom friction coefficients",
121 "generate_interpolz_py.png" )
122 sgPyQt.createMenu( act, mid )
123 sgPyQt.createTool( act, tid )
125 act = sgPyQt.createSeparator()
127 act = sgPyQt.createAction(\
128 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID,
129 "Edit boundary conditions file",
130 "Edit boundary conditions file",
131 "Create/edit the boundary conditions file for Telemac",
132 "edit_boundary_conditions_file.png")
133 sgPyQt.createMenu(act, mid)
134 sgPyQt.createTool(act, tid)
136 act = sgPyQt.createAction(\
137 GUIcontext.EDIT_LIQUID_BOUNDARY_FILE_ID,
138 "Edit liquid boundary conditions file",
139 "Edit liquid boundary conditions file",
140 "Create/edit the liquid boundary conditions file for Telemac",
141 "edit_liquid_boundary_conditions_file.png")
142 sgPyQt.createMenu(act, mid)
143 sgPyQt.createTool(act, tid)
145 act = sgPyQt.createAction(\
146 GUIcontext.EDIT_BREACHES_FILE_ID,
147 "Edit breaches file",
148 "Edit breaches file",
149 "Create/edit the breaches file for Telemac",
150 "edit_breaches_file.png")
151 sgPyQt.createMenu(act, mid)
152 sgPyQt.createTool(act, tid)
154 act = sgPyQt.createAction(\
155 GUIcontext.EDIT_INITIAL_FIELD_FILE_ID,
156 "Edit initial field file",
157 "Edit initial field file",
158 "Create/edit the initial field file for Telemac",
159 "edit_boundary_conditions_file.png" )
160 sgPyQt.createMenu( act, mid )
161 sgPyQt.createTool( act, tid )
163 act = sgPyQt.createAction(\
164 GUIcontext.CREATE_TELMA_CAS_ID,
165 "Edit cas file (English)",
166 "Edit cas file (English)",
167 "Create/edit act .cas file for Telemac (English)",
168 "create_telma_cas.png")
169 sgPyQt.createMenu(act, mid)
170 sgPyQt.createTool(act, tid)
172 act = sgPyQt.createAction(\
173 GUIcontext.CREATE_STUDY_ID,
174 "Execute a steering file",
175 "Execute a steering file",
176 "Fill formular for a normal execution",
179 sgPyQt.createMenu(act, mid)
180 sgPyQt.createTool(act, tid)
182 act = sgPyQt.createAction(\
183 GUIcontext.CREATE_PARAM_STUDY_ID,
184 "Create Parameter Study",
185 "Create Parameter Study",
186 "Create act new Parameter Study",
187 "create_param_study.png")
188 sgPyQt.createMenu(act, mid)
189 sgPyQt.createTool(act, tid)
191 act = sgPyQt.createSeparator()
193 # the following action are used in context popup
195 sgPyQt.createAction(\
196 GUIcontext.EDIT_PARAM_STUDY_ID,
199 "Edit study using python launcher")
200 sgPyQt.createAction(\
201 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID,
202 "Generate Python script",
203 "Generate Python script",
204 "Generate act Python script from the eficas date")
205 sgPyQt.createAction(\
206 GUIcontext.GEN_PARAM_STUDY_YACS_ID,
207 "Generate YACS script",
208 "Generate YACS script",
209 "Generate act YACS script from the eficas date")
211 sgPyQt.createAction(\
212 GUIcontext.RUN_STUDY_ID,
215 "Compute study using python launcher")
216 sgPyQt.createAction(\
217 GUIcontext.EDIT_STUDY_ID,
220 "Edit the selected study")
221 sgPyQt.createAction(\
222 GUIcontext.GEN_STUDY_BATCH_ID,
223 "Generate batch job",
224 "Generate batch job",
225 "Generate a batch job to run the selected study")
227 sgPyQt.createAction(\
228 GUIcontext.EDIT_TELMA_CAS_ID,
229 "Edit Steering file",
230 "Edit Steering file",
231 "Edit a Telemac-Mascaret steering file")
234 ################################################
236 ################################################
238 # study-to-context map
239 __study2context__ = {}
241 __current_context__ = None
245 ################################################
247 ################################################
250 # get active study ID
253 #return sgPyQt.getStudyId()
259 #studyId = _getStudyId()
260 #study = getStudyManager().GetStudyByID(studyId)
264 # returns True if object has children
266 def _hasChildren(sobj):
268 study = salome.myStudy
269 iter = study.NewChildIterator(sobj)
271 name = iter.Value().GetName()
280 # get current GUI context
283 global __current_context__
284 return __current_context__
287 # set and return current GUI context
288 # study ID is passed as parameter
291 global __study2context__, __current_context__
292 #if studyID not in __study2context__:
293 #__study2context__[studyID] = GUIcontext()
295 #__current_context__ = __study2context__[studyID]
296 __current_context__ = GUIcontext()
297 return __current_context__
300 # increment object counter in the map
302 def _incObjToMap(m, id):
303 if id not in m: m[id] = 0
307 ################################################
309 ################################################
311 # called when module is activated
312 # returns True if activating is successfull and False otherwise
317 # called when module is deactivated
321 # called when active study is changed
322 # active study ID is passed as parameter
323 def activeStudyChanged():
327 # called when popup menu is invoked
328 # popup menu and menu context are passed as parameters
329 def createPopupMenu(popup, context):
330 ed = getStudyEditor()
332 if salome.sg.SelectedCount() == 1:
333 # one object is selected
334 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
335 print("sobj: %s"%sobj) # strange bug with sobj is None when right clic on 3Dview in HYDROSOLVER used after HYDRO (generate AssignStrickler)
337 selectedType = ed.getTypeId(sobj)
338 if selectedType == hydro_study.TELMA_TYPE_ID:
339 popup.addAction(sgPyQt.action(GUIcontext.EDIT_TELMA_CAS_ID))
340 elif selectedType == hydro_study.PARAM_STUDY_TYPE_ID:
341 popup.addAction(sgPyQt.action(GUIcontext.EDIT_PARAM_STUDY_ID))
342 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_PYTHON_ID))
343 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_YACS_ID))
344 elif selectedType == hydro_study.STUDY_TYPE_ID:
345 popup.addAction(sgPyQt.action(GUIcontext.EDIT_STUDY_ID))
346 popup.addAction(sgPyQt.action(GUIcontext.RUN_STUDY_ID))
347 popup.addAction(sgPyQt.action(GUIcontext.GEN_STUDY_BATCH_ID))
349 # called when GUI action is activated
350 # action ID is passed as parameter
351 def OnGUIEvent(commandID):
353 dict_command[commandID]()
354 except HSGUIException as exc:
355 QMessageBox.critical(sgPyQt.getDesktop(),
356 QApplication.translate("OnGUIEvent", "Error"),
359 logger.exception("Unhandled exception caught in HYDROSOLVER GUI")
360 msg = QApplication.translate("OnGUIEvent",
361 "Unhandled error happened in HYDROSOLVER module. Please report a bug on "
362 '<a href="https://forge-pleiade.der.edf.fr/projects/salome-rex/issues">SALOME bugtracker</a>, '
363 'category "HYDROSOLVER", describing how you got there and including the following traceback:')
364 msgBox = QMessageBox(QMessageBox.Critical,
365 QApplication.translate("OnGUIEvent", "Error"),
367 parent=sgPyQt.getDesktop())
368 msgBox.setDetailedText(traceback.format_exc())
371 ################################################
372 # GUI actions implementation
373 ################################################
376 # Open Eficas for a new parametric study
378 def create_param_study():
379 EficasForParamStudyAppli()
381 # Open Eficas to edit a new parametric study
383 def edit_param_study():
384 EficasForParamStudyAppli(get_and_check_selected_file_path())
387 # Generate a python script from the eficas file
389 def generate_param_study_python():
392 ed = hydro_study.HydroStudyEditor()
393 sobj = get_and_check_selected_file_path()
394 ed.generate_study_script(sobj)
395 except SALOME.SALOME_Exception as exc:
396 salome.sg.updateObjBrowser()
397 msg = str(QApplication.translate("generate_telemac2d_python",
398 "An error happened while trying to generate telemac2d Python script:"))
399 msg += "\n" + exc.details.text
400 raise HSGUIException(msg)
403 # Generate a python script from the eficas file
405 def generate_param_study_yacs():
408 ed = hydro_study.HydroStudyEditor()
409 sobj = get_and_check_selected_file_path()
410 ed.generate_study_yacs(sobj)
411 except SALOME.SALOME_Exception as exc:
412 salome.sg.updateObjBrowser()
413 msg = str(QApplication.translate("generate_telemac2d_yacs",
414 "An error happened while trying to generate telemac2d Python script:"))
415 msg += "\n" + exc.details.text
416 raise HSGUIException(msg)
418 def open_schema_in_yacs():
419 ed = getStudyEditor()
420 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
421 filename = sobj.GetComment()
422 if filename.endswith(".comm"):
423 filename = filename[:-5] + ".xml"
424 if not os.path.isfile(filename):
425 raise HSGUIException(QApplication.translate("open_schema_in_yacs",
426 "Schema file %1 does not exist").arg(filename))
427 yg = salome.ImportComponentGUI("YACS")
428 yg.loadSchema(filename)
431 # Open dialog for boundary conditions edition
433 def edit_boundary_conditions_file():
434 desktop = sgPyQt.getDesktop()
435 dlg = BoundaryConditionsDialog(desktop)
439 # Open dialog for liquid boundaries edition
441 def edit_liquid_boundaries_file():
442 desktop = sgPyQt.getDesktop()
443 dlg = LiquidBoundariesDialog(desktop)
447 # Open dialog for breaches edition
449 def edit_breaches_file():
450 desktop = sgPyQt.getDesktop()
451 dlg = BreachesDialog(desktop)
455 # Open dialog for initial conditions edition
457 def edit_initial_field_file():
458 desktop = sgPyQt.getDesktop()
459 dlg = initialFieldDialog(desktop)
463 # Open dialog for liquid boundary conditions edition
465 def edit_liquid_boundary_file():
466 # TODO: Implement gui
467 QMessageBox.warning(sgPyQt.getDesktop(),
469 "Liquid boundary file handling not implemented yet")
473 # Open dialog for breaches file edition
475 def edit_breaches_file():
476 # TODO: Implement gui
477 QMessageBox.warning(sgPyQt.getDesktop(),
479 "Breaches file handling not implemented yet")
483 # Open dialog for interpolz.py script generation
485 def generate_interpolz_py():
486 desktop = sgPyQt.getDesktop()
487 dlg = InterpolzDlg(desktop)
491 # Open dialog for assignStrickler.py script generation
493 def generate_assignStrickler_py():
494 desktop = sgPyQt.getDesktop()
495 dlg = assignStricklerDlg(desktop)
498 def changeCoords_py():
499 desktop = sgPyQt.getDesktop()
500 dlg = changeCoordsDialog(desktop)
504 # Open dialog for boundary conditions edition
506 def generate_interpolks_py():
507 QMessageBox.warning(sgPyQt.getDesktop(),
509 "Generation of interpolks.py not implemented yet")
513 # Open dialog for creation of steering file
515 def create_telma_cas():
516 EficasForTelmaAppli(code='TELEMAC', lang='en')
519 # Open dialog for edition of steering file
521 def edit_telma_cas():
522 # TODO: See how to detect module
523 EficasForTelmaAppli(fichier=get_and_check_selected_file_path(),
524 code='TELEMAC', lang='en')
527 # Commands dictionary
530 GUIcontext.CREATE_STUDY_ID: create_case_study,
531 GUIcontext.EDIT_STUDY_ID: edit_selected_case_study,
532 GUIcontext.RUN_STUDY_ID: run_selected_case_study,
533 GUIcontext.GEN_STUDY_BATCH_ID: generate_job_for_selected_case_study,
534 GUIcontext.CREATE_TELMA_CAS_ID: create_telma_cas,
535 GUIcontext.EDIT_TELMA_CAS_ID: edit_telma_cas,
536 GUIcontext.GENERATE_INTERPOLZ_PY_ID: generate_interpolz_py,
537 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID: generate_assignStrickler_py,
538 GUIcontext.CHANGECOORDS_PY_ID: changeCoords_py,
539 GUIcontext.EDIT_LIQUID_BOUNDARY_FILE_ID: edit_liquid_boundary_file,
540 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID: edit_boundary_conditions_file,
541 GUIcontext.EDIT_BREACHES_FILE_ID: edit_breaches_file,
542 GUIcontext.EDIT_INITIAL_FIELD_FILE_ID: edit_initial_field_file,
543 GUIcontext.CREATE_PARAM_STUDY_ID: create_param_study,
544 GUIcontext.EDIT_PARAM_STUDY_ID: edit_param_study,
545 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID: generate_param_study_python,
546 GUIcontext.GEN_PARAM_STUDY_YACS_ID: generate_param_study_yacs,