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 salome.hydro.initialFieldDialog import initialFieldDialog
54 from salome.hydro.checkBoundariesDialog import checkBoundariesDialog
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_INITIAL_FIELD_FILE_ID = 962
82 CREATE_PARAM_STUDY_ID = 963
83 EDIT_PARAM_STUDY_ID = 964
84 GEN_PARAM_STUDY_PYTHON_ID = 965
85 GEN_PARAM_STUDY_YACS_ID = 966
87 CHANGECOORDS_PY_ID = 967
88 CHECK_BOUNDARY_CONDITIONS_ID = 968
91 # create top-level menu
92 mid = sgPyQt.createMenu("Hydro", -1, GUIcontext.HYDRO_MENU_ID,
93 sgPyQt.defaultMenuGroup())
95 tid = sgPyQt.createTool("Hydro")
96 # create actions and fill menu and toolbar with actions
97 act = sgPyQt.createAction(\
98 GUIcontext.CHANGECOORDS_PY_ID,
100 "Change coordinates",
101 "Change mesh coordinates",
102 "changes_coords.png")
103 sgPyQt.createMenu(act, mid)
104 sgPyQt.createTool(act, tid)
106 act = sgPyQt.createAction(\
107 GUIcontext.GENERATE_INTERPOLZ_PY_ID,
108 "Generate interpolz.py",
109 "Generate interpolz.py",
110 "Generate interpolation script for altitudes",
111 "generate_interpolz_py.png")
112 sgPyQt.createMenu(act, mid)
113 sgPyQt.createTool(act, tid)
115 act = sgPyQt.createAction(\
116 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID,
117 "Generate assignStrickler.py",
118 "Generate assignStrickler.py",
119 "Generate assignation script for bottom friction coefficients",
120 "assign_Strickler_py.png" )
121 sgPyQt.createMenu( act, mid )
122 sgPyQt.createTool( act, tid )
124 act = sgPyQt.createSeparator()
126 act = sgPyQt.createAction(\
127 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID,
128 "Edit boundary conditions file",
129 "Edit boundary conditions file",
130 "Create/edit the boundary conditions file for Telemac",
131 "edit_boundary_conditions_file.png")
132 sgPyQt.createMenu(act, mid)
133 sgPyQt.createTool(act, tid)
135 act = sgPyQt.createAction(\
136 GUIcontext.CHECK_BOUNDARY_CONDITIONS_ID,
137 "Check boundary conditions",
138 "Check boundary conditions",
139 "display a graph with boundary conditions on the mesh",
140 "check_boundary_conditions.png")
141 sgPyQt.createMenu(act, mid)
142 sgPyQt.createTool(act, tid)
144 act = sgPyQt.createAction(\
145 GUIcontext.EDIT_INITIAL_FIELD_FILE_ID,
146 "Edit initial field file",
147 "Edit initial field file",
148 "Create/edit the initial field file for Telemac",
149 "edit_initial_field_file.png" )
150 sgPyQt.createMenu( act, mid )
151 sgPyQt.createTool( act, tid )
153 act = sgPyQt.createAction(\
154 GUIcontext.CREATE_TELMA_CAS_ID,
155 "Edit cas file (English)",
156 "Edit cas file (English)",
157 "Create/edit act .cas file for Telemac (English)",
158 "create_telma_cas.png")
159 sgPyQt.createMenu(act, mid)
160 sgPyQt.createTool(act, tid)
162 act = sgPyQt.createAction(\
163 GUIcontext.CREATE_STUDY_ID,
164 "Execute a steering file",
165 "Execute a steering file",
166 "Fill formular for a normal execution",
169 sgPyQt.createMenu(act, mid)
170 sgPyQt.createTool(act, tid)
172 act = sgPyQt.createAction(\
173 GUIcontext.CREATE_PARAM_STUDY_ID,
174 "Create Parameter Study",
175 "Create Parameter Study",
176 "Create act new Parameter Study",
177 "create_param_study.png")
178 sgPyQt.createMenu(act, mid)
179 sgPyQt.createTool(act, tid)
181 act = sgPyQt.createSeparator()
183 # the following action are used in context popup
185 sgPyQt.createAction(\
186 GUIcontext.EDIT_PARAM_STUDY_ID,
189 "Edit study using python launcher")
190 sgPyQt.createAction(\
191 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID,
192 "Generate Python script",
193 "Generate Python script",
194 "Generate act Python script from the eficas date")
195 sgPyQt.createAction(\
196 GUIcontext.GEN_PARAM_STUDY_YACS_ID,
197 "Generate YACS script",
198 "Generate YACS script",
199 "Generate act YACS script from the eficas date")
201 sgPyQt.createAction(\
202 GUIcontext.RUN_STUDY_ID,
205 "Compute study using python launcher")
206 sgPyQt.createAction(\
207 GUIcontext.EDIT_STUDY_ID,
210 "Edit the selected study")
211 sgPyQt.createAction(\
212 GUIcontext.GEN_STUDY_BATCH_ID,
213 "Generate batch job",
214 "Generate batch job",
215 "Generate a batch job to run the selected study")
217 sgPyQt.createAction(\
218 GUIcontext.EDIT_TELMA_CAS_ID,
219 "Edit Steering file",
220 "Edit Steering file",
221 "Edit a Telemac-Mascaret steering file")
224 ################################################
226 ################################################
228 # study-to-context map
229 __study2context__ = {}
231 __current_context__ = None
235 ################################################
237 ################################################
240 # get active study ID
243 #return sgPyQt.getStudyId()
249 #studyId = _getStudyId()
250 #study = getStudyManager().GetStudyByID(studyId)
254 # returns True if object has children
256 def _hasChildren(sobj):
258 study = salome.myStudy
259 iter = study.NewChildIterator(sobj)
261 name = iter.Value().GetName()
270 # get current GUI context
273 global __current_context__
274 return __current_context__
277 # set and return current GUI context
278 # study ID is passed as parameter
281 global __study2context__, __current_context__
282 #if studyID not in __study2context__:
283 #__study2context__[studyID] = GUIcontext()
285 #__current_context__ = __study2context__[studyID]
286 __current_context__ = GUIcontext()
287 return __current_context__
290 # increment object counter in the map
292 def _incObjToMap(m, id):
293 if id not in m: m[id] = 0
297 ################################################
299 ################################################
301 # called when module is activated
302 # returns True if activating is successfull and False otherwise
307 # called when module is deactivated
311 # called when active study is changed
312 # active study ID is passed as parameter
313 def activeStudyChanged():
317 # called when popup menu is invoked
318 # popup menu and menu context are passed as parameters
319 def createPopupMenu(popup, context):
320 ed = getStudyEditor()
322 if salome.sg.SelectedCount() == 1:
323 # one object is selected
324 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
325 print("sobj: %s"%sobj) # strange bug with sobj is None when right clic on 3Dview in HYDROSOLVER used after HYDRO (generate AssignStrickler)
327 selectedType = ed.getTypeId(sobj)
328 if selectedType == hydro_study.TELMA_TYPE_ID:
329 popup.addAction(sgPyQt.action(GUIcontext.EDIT_TELMA_CAS_ID))
330 elif selectedType == hydro_study.PARAM_STUDY_TYPE_ID:
331 popup.addAction(sgPyQt.action(GUIcontext.EDIT_PARAM_STUDY_ID))
332 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_PYTHON_ID))
333 popup.addAction(sgPyQt.action(GUIcontext.GEN_PARAM_STUDY_YACS_ID))
334 elif selectedType == hydro_study.STUDY_TYPE_ID:
335 popup.addAction(sgPyQt.action(GUIcontext.EDIT_STUDY_ID))
336 popup.addAction(sgPyQt.action(GUIcontext.RUN_STUDY_ID))
337 popup.addAction(sgPyQt.action(GUIcontext.GEN_STUDY_BATCH_ID))
339 # called when GUI action is activated
340 # action ID is passed as parameter
341 def OnGUIEvent(commandID):
343 dict_command[commandID]()
344 except HSGUIException as exc:
345 QMessageBox.critical(sgPyQt.getDesktop(),
346 QApplication.translate("OnGUIEvent", "Error"),
349 logger.exception("Unhandled exception caught in HYDROSOLVER GUI")
350 msg = QApplication.translate("OnGUIEvent",
351 "Unhandled error happened in HYDROSOLVER module. Please report a bug on "
352 '<a href="https://forge-pleiade.der.edf.fr/projects/salome-rex/issues">SALOME bugtracker</a>, '
353 'category "HYDROSOLVER", describing how you got there and including the following traceback:')
354 msgBox = QMessageBox(QMessageBox.Critical,
355 QApplication.translate("OnGUIEvent", "Error"),
357 parent=sgPyQt.getDesktop())
358 msgBox.setDetailedText(traceback.format_exc())
361 ################################################
362 # GUI actions implementation
363 ################################################
366 # Open Eficas for a new parametric study
368 def create_param_study():
369 EficasForParamStudyAppli()
371 # Open Eficas to edit a new parametric study
373 def edit_param_study():
374 EficasForParamStudyAppli(get_and_check_selected_file_path())
377 # Generate a python script from the eficas file
379 def generate_param_study_python():
382 ed = hydro_study.HydroStudyEditor()
383 sobj = get_and_check_selected_file_path()
384 python_file = ed.generate_study_script(sobj)
385 except SALOME.SALOME_Exception as exc:
386 salome.sg.updateObjBrowser()
387 msg = str(QApplication.translate("generate_telemac2d_python",
388 "An error happened while trying to generate telemac2d Python script:"))
389 msg += "\n" + exc.details.text
390 raise HSGUIException(msg)
391 QMessageBox.information(sgPyQt.getDesktop(),
393 "Generated Python script in:\n{}".format(python_file))
396 # Generate a python script from the eficas file
398 def generate_param_study_yacs():
401 ed = hydro_study.HydroStudyEditor()
402 sobj = get_and_check_selected_file_path()
403 yacs_file = ed.generate_study_yacs(sobj)
404 except SALOME.SALOME_Exception as exc:
405 salome.sg.updateObjBrowser()
406 msg = str(QApplication.translate("generate_telemac2d_yacs",
407 "An error happened while trying to generate telemac2d Python script:"))
408 msg += "\n" + exc.details.text
409 raise HSGUIException(msg)
410 QMessageBox.information(sgPyQt.getDesktop(),
412 "Generated YACS scheme in:\n{}".format(yacs_file))
414 def open_schema_in_yacs():
415 ed = getStudyEditor()
416 sobj = ed.study.FindObjectID(salome.sg.getSelected(0))
417 filename = sobj.GetComment()
418 if filename.endswith(".comm"):
419 filename = filename[:-5] + ".xml"
420 if not os.path.isfile(filename):
421 raise HSGUIException(QApplication.translate("open_schema_in_yacs",
422 "Schema file %1 does not exist").arg(filename))
423 yg = salome.ImportComponentGUI("YACS")
424 yg.loadSchema(filename)
427 # Open dialog for boundary conditions edition
429 def edit_boundary_conditions_file():
430 desktop = sgPyQt.getDesktop()
431 dlg = BoundaryConditionsDialog(desktop)
435 # Open dialog for initial conditions edition
437 def edit_initial_field_file():
438 desktop = sgPyQt.getDesktop()
439 dlg = initialFieldDialog(desktop)
443 # Open dialog for initial conditions edition
445 def check_boundaries():
446 desktop = sgPyQt.getDesktop()
447 dlg = checkBoundariesDialog(desktop)
451 # Open dialog for interpolz.py script generation
453 def generate_interpolz_py():
454 desktop = sgPyQt.getDesktop()
455 dlg = InterpolzDlg(desktop)
459 # Open dialog for assignStrickler.py script generation
461 def generate_assignStrickler_py():
462 desktop = sgPyQt.getDesktop()
463 dlg = assignStricklerDlg(desktop)
466 def changeCoords_py():
467 desktop = sgPyQt.getDesktop()
468 dlg = changeCoordsDialog(desktop)
472 # Open dialog for boundary conditions edition
474 def generate_interpolks_py():
475 QMessageBox.warning(sgPyQt.getDesktop(),
477 "Generation of interpolks.py not implemented yet")
481 # Open dialog for creation of steering file
483 def create_telma_cas():
484 EficasForTelmaAppli(code='TELEMAC', lang='en')
487 # Open dialog for edition of steering file
489 def edit_telma_cas():
490 # TODO: See how to detect module
491 EficasForTelmaAppli(fichier=get_and_check_selected_file_path(),
492 code='TELEMAC', lang='en')
495 # Commands dictionary
498 GUIcontext.CREATE_STUDY_ID: create_case_study,
499 GUIcontext.EDIT_STUDY_ID: edit_selected_case_study,
500 GUIcontext.RUN_STUDY_ID: run_selected_case_study,
501 GUIcontext.GEN_STUDY_BATCH_ID: generate_job_for_selected_case_study,
502 GUIcontext.CREATE_TELMA_CAS_ID: create_telma_cas,
503 GUIcontext.EDIT_TELMA_CAS_ID: edit_telma_cas,
504 GUIcontext.GENERATE_INTERPOLZ_PY_ID: generate_interpolz_py,
505 GUIcontext.GENERATE_ASSIGNSTRICKLER_PY_ID: generate_assignStrickler_py,
506 GUIcontext.CHANGECOORDS_PY_ID: changeCoords_py,
507 GUIcontext.EDIT_BOUNDARY_CONDITIONS_FILE_ID: edit_boundary_conditions_file,
508 GUIcontext.CHECK_BOUNDARY_CONDITIONS_ID: check_boundaries,
509 GUIcontext.EDIT_INITIAL_FIELD_FILE_ID: edit_initial_field_file,
510 GUIcontext.CREATE_PARAM_STUDY_ID: create_param_study,
511 GUIcontext.EDIT_PARAM_STUDY_ID: edit_param_study,
512 GUIcontext.GEN_PARAM_STUDY_PYTHON_ID: generate_param_study_python,
513 GUIcontext.GEN_PARAM_STUDY_YACS_ID: generate_param_study_yacs,