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):
256 study = salome.myStudy
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
279 global __study2context__, __current_context__
280 #if studyID not in __study2context__:
281 #__study2context__[studyID] = GUIcontext()
283 #__current_context__ = __study2context__[studyID]
284 __current_context__ = GUIcontext()
285 return __current_context__
288 # increment object counter in the map
290 def _incObjToMap(m, id):
291 if id not in m: m[id] = 0
295 ################################################
297 ################################################
299 # called when module is activated
300 # returns True if activating is successfull and False otherwise
305 # called when module is deactivated
309 # called when active study is changed
310 # active study ID is passed as parameter
311 def activeStudyChanged():
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()
320 if salome.sg.SelectedCount() == 1:
321 # one object is selected
322 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
323 print("sobj: %s"%sobj) # strange bug with sobj is None when right clic on 3Dview in HYDROSOLVER used after HYDRO (generate AssignStrickler)
325 selectedType = ed.getTypeId(sobj)
326 if selectedType == hydro_study.TELMA_TYPE_ID:
327 popup.addAction(sgPyQt.action(GUIcontext.EDIT_TELMA_CAS_ID))
328 elif selectedType == hydro_study.PARAM_STUDY_TYPE_ID:
329 popup.addAction(sgPyQt.action(GUIcontext.EDIT_PARAM_STUDY_ID))
330 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_PYTHON_ID))
331 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_YACS_ID))
332 elif selectedType == hydro_study.STUDY_TYPE_ID:
333 popup.addAction(sgPyQt.action(GUIcontext.EDIT_STUDY_ID))
334 popup.addAction(sgPyQt.action(GUIcontext.RUN_STUDY_ID))
335 popup.addAction(sgPyQt.action(GUIcontext.GEN_STUDY_BATCH_ID))
337 # called when GUI action is activated
338 # action ID is passed as parameter
339 def OnGUIEvent(commandID):
341 dict_command[commandID]()
342 except HSGUIException as exc:
343 QMessageBox.critical(sgPyQt.getDesktop(),
344 QApplication.translate("OnGUIEvent", "Error"),
347 logger.exception("Unhandled exception caught in HYDROSOLVER GUI")
348 msg = QApplication.translate("OnGUIEvent",
349 "Unhandled error happened in HYDROSOLVER module. Please report a bug on "
350 '<a href="https://forge-pleiade.der.edf.fr/projects/salome-rex/issues">SALOME bugtracker</a>, '
351 'category "HYDROSOLVER", describing how you got there and including the following traceback:')
352 msgBox = QMessageBox(QMessageBox.Critical,
353 QApplication.translate("OnGUIEvent", "Error"),
355 parent=sgPyQt.getDesktop())
356 msgBox.setDetailedText(traceback.format_exc())
359 ################################################
360 # GUI actions implementation
361 ################################################
364 # Open Eficas for a new parametric study
366 def create_param_study():
367 EficasForParamStudyAppli()
369 # Open Eficas to edit a new parametric study
371 def edit_param_study():
372 EficasForParamStudyAppli(get_and_check_selected_file_path())
375 # Generate a python script from the eficas file
377 def generate_param_study_python():
380 ed = hydro_study.HydroStudyEditor()
381 sobj = get_and_check_selected_file_path()
382 ed.generate_study_script(sobj)
383 except SALOME.SALOME_Exception as exc:
384 salome.sg.updateObjBrowser()
385 msg = str(QApplication.translate("generate_telemac2d_python",
386 "An error happened while trying to generate telemac2d Python script:"))
387 msg += "\n" + exc.details.text
388 raise HSGUIException(msg)
391 # Generate a python script from the eficas file
393 def generate_param_study_yacs():
396 ed = hydro_study.HydroStudyEditor()
397 sobj = get_and_check_selected_file_path()
398 ed.generate_study_yacs(sobj)
399 except SALOME.SALOME_Exception as exc:
400 salome.sg.updateObjBrowser()
401 msg = str(QApplication.translate("generate_telemac2d_yacs",
402 "An error happened while trying to generate telemac2d Python script:"))
403 msg += "\n" + exc.details.text
404 raise HSGUIException(msg)
406 def open_schema_in_yacs():
407 ed = getStudyEditor()
408 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
409 filename = sobj.GetComment()
410 if filename.endswith(".comm"):
411 filename = filename[:-5] + ".xml"
412 if not os.path.isfile(filename):
413 raise HSGUIException(QApplication.translate("open_schema_in_yacs",
414 "Schema file %1 does not exist").arg(filename))
415 yg = salome.ImportComponentGUI("YACS")
416 yg.loadSchema(filename)
419 # Open dialog for boundary conditions edition
421 def edit_boundary_conditions_file():
422 desktop = sgPyQt.getDesktop()
423 dlg = BoundaryConditionsDialog(desktop)
427 # Open dialog for liquid boundaries edition
429 def edit_liquid_boundaries_file():
430 desktop = sgPyQt.getDesktop()
431 dlg = LiquidBoundariesDialog(desktop)
435 # Open dialog for breaches edition
437 def edit_breaches_file():
438 desktop = sgPyQt.getDesktop()
439 dlg = BreachesDialog(desktop)
443 # Open dialog for initial conditions edition
445 def edit_initial_conditions_file():
446 desktop = sgPyQt.getDesktop()
447 dlg = InitialConditionsDialog(desktop)
451 # Open dialog for liquid boundary conditions edition
453 def edit_liquid_boundary_file():
454 # TODO: Implement gui
455 QMessageBox.warning(sgPyQt.getDesktop(),
457 "Liquid boundary file handling not implemented yet")
461 # Open dialog for breaches file edition
463 def edit_breaches_file():
464 # TODO: Implement gui
465 QMessageBox.warning(sgPyQt.getDesktop(),
467 "Breaches file handling not implemented yet")
471 # Open dialog for interpolz.py script generation
473 def generate_interpolz_py():
474 desktop = sgPyQt.getDesktop()
475 dlg = InterpolzDlg(desktop)
479 # Open dialog for assignStrickler.py script generation
481 def generate_assignStrickler_py():
482 desktop = sgPyQt.getDesktop()
483 dlg = assignStricklerDlg(desktop)
487 # Open dialog for boundary conditions edition
489 def generate_interpolks_py():
490 QMessageBox.warning(sgPyQt.getDesktop(),
492 "Generation of interpolks.py not implemented yet")
496 # Open dialog for creation of steering file
498 def create_telma_cas():
499 EficasForTelmaAppli(code='TELEMAC', lang='en')
502 # Open dialog for edition of steering file
504 def edit_telma_cas():
505 # TODO: See how to detect module
506 EficasForTelmaAppli(fichier=get_and_check_selected_file_path(),
507 code='TELEMAC', lang='en')
510 # Commands dictionary
513 GUIcontext.CREATE_STUDY_ID: create_case_study,
514 GUIcontext.EDIT_STUDY_ID: edit_selected_case_study,
515 GUIcontext.RUN_STUDY_ID: run_selected_case_study,
516 GUIcontext.GEN_STUDY_BATCH_ID: generate_job_for_selected_case_study,
517 GUIcontext.CREATE_TELMA_CAS_ID: create_telma_cas,
518 GUIcontext.EDIT_TELMA_CAS_ID: edit_telma_cas,
519 GUIcontext.GENERATE_INTERPOLZ_PY_ID: generate_interpolz_py,
520 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID: generate_assignStrickler_py,
521 GUIcontext.EDIT_LIQUID_BOUNDARY_FILE_ID: edit_liquid_boundary_file,
522 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID: edit_boundary_conditions_file,
523 GUIcontext.EDIT_BREACHES_FILE_ID: edit_breaches_file,
524 GUIcontext.EDIT_INITIAL_CONDITIONS_FILE_ID: edit_initial_conditions_file,
525 GUIcontext.CREATE_PARAM_STUDY_ID: create_param_study,
526 GUIcontext.EDIT_PARAM_STUDY_ID: edit_param_study,
527 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID: generate_param_study_python,
528 GUIcontext.GEN_PARAM_STUDY_YACS_ID: generate_param_study_yacs,