mirror of https://gitlab.com/pamhyr/pamhyr2
769 lines
23 KiB
Python
769 lines
23 KiB
Python
# MainWindow.py -- Pamhyr
|
|
# Copyright (C) 2023 INRAE
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import logging
|
|
import subprocess
|
|
from queue import Queue
|
|
|
|
from PyQt5 import QtGui
|
|
from PyQt5.QtGui import (
|
|
QKeySequence,
|
|
)
|
|
|
|
from PyQt5.QtCore import (
|
|
QTranslator, QEvent
|
|
)
|
|
from PyQt5.QtWidgets import (
|
|
QMainWindow, QApplication, QAction,
|
|
QFileDialog, QShortcut, QMenu, QToolBar,
|
|
QMessageBox,
|
|
)
|
|
from PyQt5.uic import loadUi
|
|
|
|
from View.Tools.ASubWindow import WindowToolKit
|
|
from View.Tools.ListedSubWindow import ListedSubWindow
|
|
from View.DummyWindow import DummyWindow
|
|
|
|
from View.Configure.Window import ConfigureWindow
|
|
from View.Study.Window import NewStudyWindow
|
|
from View.About.Window import AboutWindow
|
|
from View.Network.Window import NetworkWindow
|
|
from View.Geometry.Window import GeometryWindow
|
|
from View.BoundaryCondition.Window import BoundaryConditionWindow
|
|
from View.LateralContribution.Window import LateralContributionWindow
|
|
from View.InitialConditions.Window import InitialConditionsWindow
|
|
from View.Stricklers.Window import StricklersWindow
|
|
from View.Frictions.Window import FrictionsWindow
|
|
from View.SedimentLayers.Window import SedimentLayersWindow
|
|
from View.SedimentLayers.Reach.Window import ReachSedimentLayersWindow
|
|
from View.SolverParameters.Window import SolverParametersWindow
|
|
from View.RunSolver.Window import SelectSolverWindow, SolverLogWindow
|
|
from View.CheckList.Window import CheckListWindow
|
|
from View.Results.Window import ResultsWindow
|
|
from View.Doc.Window import DocWindow
|
|
from View.Debug.Window import ReplWindow
|
|
|
|
from Model.Study import Study
|
|
|
|
logger = logging.getLogger()
|
|
|
|
no_model_action = [
|
|
"action_menu_new", "action_menu_open", "action_menu_import_mage",
|
|
"action_menu_import_rubarbe", "action_toolBar_open",
|
|
]
|
|
|
|
model_action = [
|
|
"action_menu_close", "action_menu_edit", "action_menu_save",
|
|
"action_menu_save_as", "action_toolBar_close", "action_toolBar_save",
|
|
"action_menu_numerical_parameter",
|
|
]
|
|
|
|
other_model_action = [
|
|
"action_toolBar_run_solver", "action_toolBar_kill_solver"
|
|
]
|
|
|
|
define_model_action = [
|
|
# Toolbar
|
|
"action_toolBar_network", "action_toolBar_geometry",
|
|
"action_toolBar_mesh", "action_toolBar_run_meshing_tool",
|
|
"action_toolBar_boundary_cond", "action_toolBar_lateral_contrib",
|
|
"action_toolBar_spills", "action_toolBar_frictions",
|
|
"action_toolBar_stricklers", "action_toolBar_building",
|
|
"action_toolBar_initial_cond",
|
|
# Menu
|
|
"action_menu_run_solver", "action_menu_numerical_parameter",
|
|
"action_menu_edit_network", "action_menu_edit_geometry",
|
|
"action_menu_boundary_conditions", "action_menu_initial_conditions",
|
|
"action_menu_edit_friction", "action_menu_edit_lateral_contribution",
|
|
"action_menu_run_solver", "action_menu_sediment_layers",
|
|
"action_menu_edit_reach_sediment_layers"
|
|
]
|
|
|
|
action = (
|
|
no_model_action + model_action + define_model_action
|
|
)
|
|
|
|
class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|
def __init__(self, conf=None):
|
|
super(ApplicationWindow, self).__init__()
|
|
|
|
self._close_question = False
|
|
|
|
# App Configuration
|
|
self.conf = conf
|
|
|
|
# Model
|
|
self._study = None
|
|
|
|
# Results
|
|
self._last_solver = None
|
|
self._last_results = None
|
|
|
|
# UI
|
|
self.ui = loadUi(
|
|
os.path.join(os.path.dirname(__file__), "ui", "MainWindow.ui"),
|
|
self
|
|
)
|
|
|
|
self.setup_sc()
|
|
self.setup_connection()
|
|
self.default_style()
|
|
self.setup_debug_mode(init = True)
|
|
|
|
self.trans = QTranslator(self)
|
|
#self.ui.retranslateUi()
|
|
|
|
if self.conf.last_study != "" and not self.conf.close_correctly:
|
|
self.dialog_reopen_study()
|
|
|
|
def set_title(self):
|
|
title = "(dbg) " if self.conf.debug else ""
|
|
|
|
if self._study is not None:
|
|
title += f"Pamhyr2 - {self._study.name}"
|
|
self.setWindowTitle(title)
|
|
else:
|
|
title += "Pamhyr2"
|
|
self.setWindowTitle(title)
|
|
|
|
def enable_actions(self, action:str, enable:bool):
|
|
"""Enable of disable an action componant
|
|
|
|
Args:
|
|
action: Action to enable/disable
|
|
enable: True to Enable, or False to disable
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
logger.debug(f"Set {action} to {enable}")
|
|
self.findChild(QAction, action).setEnabled(enable)
|
|
|
|
def setup_sc(self):
|
|
# self._run_sc = QShortcut(QKeySequence("F5"), self)
|
|
return
|
|
|
|
def setup_connection(self):
|
|
"""Connect action to callback function
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
actions = {
|
|
# Menu action
|
|
"action_menu_config": self.open_configure,
|
|
"action_menu_new": self.open_new_study,
|
|
"action_menu_edit": self.open_edit_study,
|
|
"action_menu_open": self.open_model,
|
|
"action_menu_save": self.save_study,
|
|
"action_menu_save_as": self.save_as_study,
|
|
"action_menu_numerical_parameter": self.open_solver_parameters,
|
|
"action_menu_edit_network": self.open_network,
|
|
"action_menu_edit_geometry": self.open_geometry,
|
|
"action_menu_boundary_conditions": self.open_boundary_cond,
|
|
"action_menu_initial_conditions": self.open_initial_conditions,
|
|
"action_menu_edit_friction": self.open_frictions,
|
|
"action_menu_edit_lateral_contribution": self.open_lateral_contrib,
|
|
"action_menu_run_solver": self.run_solver,
|
|
"action_menu_sediment_layers": self.open_sediment_layers,
|
|
"action_menu_edit_reach_sediment_layers": self.open_reach_sediment_layers,
|
|
"action_menu_results_last": self.open_last_results,
|
|
"action_menu_Pamhyr": self.open_doc_user,
|
|
"action_menu_Pamhyr_dev": self.open_doc_dev,
|
|
## Help
|
|
"action_menu_about": self.open_about,
|
|
# ToolBar action
|
|
"action_toolBar_quit": self.close,
|
|
"action_toolBar_open": self.open_model,
|
|
"action_toolBar_save": self.save_study,
|
|
"action_toolBar_close": self.close_model,
|
|
"action_toolBar_run_solver": self.run_solver,
|
|
## Current actions
|
|
"action_toolBar_network": self.open_network,
|
|
"action_toolBar_geometry": self.open_geometry,
|
|
"action_toolBar_mesh": lambda: self.open_dummy("Mesh"),
|
|
"action_toolBar_run_meshing_tool": self.open_solver_parameters,
|
|
"action_toolBar_boundary_cond": self.open_boundary_cond,
|
|
"action_toolBar_lateral_contrib": self.open_lateral_contrib,
|
|
"action_toolBar_spills": lambda: self.open_dummy("Deversement"),
|
|
"action_toolBar_stricklers": self.open_stricklers,
|
|
"action_toolBar_frictions": self.open_frictions,
|
|
"action_toolBar_building": lambda: self.open_dummy("Ouvrages"),
|
|
"action_toolBar_initial_cond": self.open_initial_conditions,
|
|
}
|
|
|
|
for action in actions:
|
|
logger.debug("Setup connection : " + action)
|
|
self.findChild(QAction, action)\
|
|
.triggered.connect(actions[action])
|
|
# action.triggered.connect(actions[action])
|
|
|
|
# self._run_sc.activated.connect(self.run_solver)
|
|
|
|
def changeEvent(self, event):
|
|
if event.type() == QEvent.LanguageChange:
|
|
self.retranslateUi()
|
|
super(ApplicationWindow, self).changeEvent(event)
|
|
|
|
def close(self):
|
|
if self._study is not None and not self._study.is_saved:
|
|
self._close_question = True
|
|
if self.dialog_close():
|
|
# PAMHYR is close correctly (no crash)
|
|
self.conf.set_close_correctly()
|
|
|
|
super(ApplicationWindow, self).close()
|
|
else:
|
|
self._close_question = False
|
|
else:
|
|
# PAMHYR is close correctly (no crash)
|
|
self.conf.set_close_correctly()
|
|
|
|
super(ApplicationWindow, self).close()
|
|
|
|
def closeEvent(self, event):
|
|
if not self._close_question:
|
|
if self._study is not None and not self._study.is_saved:
|
|
if self.dialog_close(cancel = False):
|
|
# PAMHYR is close correctly (no crash)
|
|
self.conf.set_close_correctly()
|
|
super(ApplicationWindow, self).closeEvent(event)
|
|
else:
|
|
super(ApplicationWindow, self).closeEvent(event)
|
|
|
|
def default_style(self):
|
|
"""Set default window style
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
self.update_enable_action()
|
|
# Maximise window
|
|
self.showMaximized()
|
|
|
|
def set_debug_lvl(self, debug = True):
|
|
if debug:
|
|
logger.setLevel(logging.DEBUG)
|
|
logger.info("Set logging level to DEBUG")
|
|
else:
|
|
logger.setLevel(logging.INFO)
|
|
logger.info("Set logging level to INFO")
|
|
|
|
def setup_debug_mode(self, init = False):
|
|
menu = self.findChild(QMenu, "menu_help")
|
|
self.set_title()
|
|
|
|
if init:
|
|
self.debug_action = QAction("Debug", self)
|
|
self.debug_action.setStatusTip("Debug")
|
|
self.debug_action.triggered.connect(self.open_debug)
|
|
|
|
self.debug_sqlite_action = QAction("Debug SQLite", self)
|
|
self.debug_sqlite_action.setStatusTip("Open SQLite debuging tool (sqlitebrowser)")
|
|
self.debug_sqlite_action.triggered.connect(self.open_sqlite)
|
|
|
|
if self.conf.debug:
|
|
menu.addAction(self.debug_action)
|
|
menu.addAction(self.debug_sqlite_action)
|
|
self.set_debug_lvl(debug = True)
|
|
else:
|
|
if self.conf.debug:
|
|
menu.addAction(self.debug_action)
|
|
menu.addAction(self.debug_sqlite_action)
|
|
self.set_debug_lvl(debug = True)
|
|
else:
|
|
menu.removeAction(self.debug_action)
|
|
menu.removeAction(self.debug_sqlite_action)
|
|
self.set_debug_lvl(debug = False)
|
|
|
|
#########
|
|
# MODEL #
|
|
#########
|
|
|
|
def get_model(self):
|
|
return self._study
|
|
|
|
def set_model(self, model):
|
|
self._study = model
|
|
self.update_enable_action()
|
|
self.conf.set_last_study(self._study.filename)
|
|
self.set_title()
|
|
|
|
def close_model(self):
|
|
self._study = None
|
|
self.update_enable_action()
|
|
self.conf.set_close_correctly()
|
|
self.set_title()
|
|
|
|
def update_enable_action(self):
|
|
"""Update status of action componante
|
|
|
|
Update status of action componant, enable or disable in
|
|
function of model state
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
no_model = self._study is None
|
|
|
|
for action in no_model_action:
|
|
self.enable_actions(action, no_model)
|
|
|
|
for action in define_model_action + other_model_action:
|
|
self.enable_actions(action, not no_model)
|
|
|
|
for action in model_action:
|
|
self.enable_actions(action, not no_model)
|
|
|
|
def set_results(self, solver, results):
|
|
self._last_solver = solver
|
|
self._last_results = results
|
|
|
|
self.enable_actions("action_menu_results_last", True)
|
|
|
|
############
|
|
# FEATURES #
|
|
############
|
|
|
|
def open_study(self, filename):
|
|
"""Open a study
|
|
|
|
Args:
|
|
filename: The study path
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
self.set_model(Study.open(filename))
|
|
logger.info(f"Open Study - {self._study.name}")
|
|
self.set_title()
|
|
|
|
def save_study(self):
|
|
"""Save current study
|
|
|
|
Save current study, if study as no associate file, open a
|
|
file dialog.
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
if self._study.filename is None or self._study.filename == "":
|
|
file_name, _ = QFileDialog.getSaveFileName(
|
|
self, "Save File",
|
|
"", "Pamhyr(*.pamhyr)"
|
|
)
|
|
|
|
if file_name.rsplit(".", 1)[-1] == "pamhyr":
|
|
self._study.filename = file_name
|
|
else:
|
|
self._study.filename = file_name + ".pamhyr"
|
|
|
|
if self._study.is_saved:
|
|
return
|
|
|
|
logger.info("Save...")
|
|
self._study.save()
|
|
|
|
def save_as_study(self):
|
|
"""Save current study as new file
|
|
|
|
Save current study as new file, if study as no associate file,
|
|
open a file dialog.
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
file_name, _ = QFileDialog.getSaveFileName(
|
|
self, "Save File",
|
|
"", "Pamhyr(*.pamhyr)"
|
|
)
|
|
|
|
if file_name[-4:] == ".pamhyr":
|
|
self._study.filename = file_name
|
|
else:
|
|
self._study.filename = file_name + ".pamhyr"
|
|
|
|
self._study.save()
|
|
|
|
##################
|
|
# MSG AND DIALOG #
|
|
##################
|
|
|
|
def msg_select_reach(self):
|
|
self.message_box("Please select a reach",
|
|
"Geometry edition need a reach selected "
|
|
"into river network window to work on it")
|
|
|
|
def dialog_reopen_study(self):
|
|
dlg = QMessageBox(self)
|
|
|
|
dlg.setWindowTitle("Last open study")
|
|
dlg.setText("Do you want to open again the last open study?")
|
|
opt = QMessageBox.Cancel | QMessageBox.Ok #| QMessageBox.Open
|
|
|
|
dlg.setStandardButtons(opt)
|
|
dlg.setIcon(QMessageBox.Question)
|
|
|
|
res = dlg.exec()
|
|
|
|
if res == QMessageBox.Ok:
|
|
self.open_study(self.conf.last_study)
|
|
return True
|
|
elif res == QMessageBox.Open:
|
|
self.open_model()
|
|
return True
|
|
elif res == QMessageBox.Cancel:
|
|
return False
|
|
|
|
def dialog_close(self, cancel = True):
|
|
dlg = QMessageBox(self)
|
|
|
|
dlg.setWindowTitle("Close PAMHYR without saving study")
|
|
dlg.setText("Do you want to save current study before PAMHYR close ?")
|
|
opt = QMessageBox.Save | QMessageBox.Ignore
|
|
if cancel:
|
|
opt |= QMessageBox.Cancel
|
|
|
|
dlg.setStandardButtons(opt)
|
|
dlg.setIcon(QMessageBox.Warning)
|
|
|
|
res = dlg.exec()
|
|
|
|
if res == QMessageBox.Save:
|
|
self.save_study()
|
|
return True
|
|
elif res == QMessageBox.Ignore:
|
|
return True
|
|
elif res == QMessageBox.Cancel:
|
|
return False
|
|
|
|
#############
|
|
# SUBWINDOW #
|
|
#############
|
|
|
|
def open_configure(self):
|
|
"""Open configure window
|
|
|
|
Open PamHyr configure window
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
self.config = ConfigureWindow(config=self.conf, parent=self)
|
|
self.config.show()
|
|
|
|
def open_about(self):
|
|
"""Open about window
|
|
|
|
Open a new window with information about PamHyr
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
self.about = AboutWindow(parent=self)
|
|
self.about.show()
|
|
|
|
def open_model(self):
|
|
"""Open file dialog to select saved model
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
if self._study is None:
|
|
dialog = QFileDialog(self)
|
|
dialog.setFileMode(QFileDialog.FileMode.ExistingFile)
|
|
dialog.setDefaultSuffix(".pamhyr")
|
|
#dialog.setFilter(dialog.filter() | QtCore.QDir.Hidden)
|
|
dialog.setNameFilters(['PamHyr (*.pamhyr)'])
|
|
dialog.setDirectory(os.path.dirname(self.conf.last_study))
|
|
|
|
if dialog.exec_():
|
|
file_name = dialog.selectedFiles()
|
|
self.open_study(file_name[0])
|
|
|
|
def open_new_study(self):
|
|
"""Open dialog to set new study
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
if self._study is None:
|
|
self.new_study = NewStudyWindow(parent=self)
|
|
self.new_study.show()
|
|
|
|
def open_edit_study(self):
|
|
"""Open dialog to set new study
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
if not self._study is None:
|
|
self.new_study = NewStudyWindow(study=self._study, parent=self)
|
|
self.new_study.show()
|
|
|
|
def open_network(self):
|
|
"""Open network dialog
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
if self._study is not None:
|
|
if not self.sub_win_exists("River network"):
|
|
self.network = NetworkWindow(study=self._study, parent=self)
|
|
self.network.show()
|
|
else:
|
|
self.network.activateWindow()
|
|
|
|
def open_geometry(self):
|
|
"""Open geometry window
|
|
|
|
Returns:
|
|
Nothing
|
|
"""
|
|
if (self._study is not None and self._study.river.has_current_reach()):
|
|
geometry = self.sub_win_filter_first(
|
|
"Geometry",
|
|
contain = [self._study.river.current_reach().name]
|
|
)
|
|
|
|
if geometry is None:
|
|
geometry = GeometryWindow(study=self._study, config=self.conf, parent=self)
|
|
geometry.show()
|
|
else:
|
|
geometry.activateWindow()
|
|
else:
|
|
self.msg_select_reach()
|
|
|
|
def open_boundary_cond(self):
|
|
bound = self.sub_win_filter_first(
|
|
"Boundary conditions",
|
|
contain = []
|
|
)
|
|
|
|
if bound is None:
|
|
bound = BoundaryConditionWindow(study = self._study, parent = self)
|
|
bound.show()
|
|
else:
|
|
bound.activateWindow()
|
|
|
|
def open_lateral_contrib(self):
|
|
lateral = self.sub_win_filter_first(
|
|
"Lateral contribution",
|
|
contain = []
|
|
)
|
|
|
|
if lateral is None:
|
|
lateral = LateralContributionWindow(study = self._study, parent = self)
|
|
lateral.show()
|
|
else:
|
|
lateral.activateWindow()
|
|
|
|
def open_stricklers(self):
|
|
strick = self.sub_win_filter_first(
|
|
"Stricklers",
|
|
contain = []
|
|
)
|
|
|
|
if strick is None:
|
|
strick = StricklersWindow(
|
|
study = self._study,
|
|
config = self.conf,
|
|
parent = self
|
|
)
|
|
strick.show()
|
|
else:
|
|
strick.activateWindow()
|
|
|
|
def open_frictions(self):
|
|
if (self._study is not None and
|
|
self._study.river.has_current_reach()):
|
|
|
|
frictions = self.sub_win_filter_first(
|
|
"Frictions",
|
|
contain = [self._study.river.current_reach().name]
|
|
)
|
|
|
|
if frictions is None:
|
|
frictions = FrictionsWindow(
|
|
study = self._study,
|
|
parent = self
|
|
)
|
|
frictions.show()
|
|
else:
|
|
frictions.activateWindow()
|
|
else:
|
|
self.msg_select_reach()
|
|
|
|
def open_initial_conditions(self):
|
|
if self._study.river.has_current_reach():
|
|
initial = self.sub_win_filter_first(
|
|
"Initial condition",
|
|
contain = [self._study.river.current_reach().name]
|
|
)
|
|
|
|
if initial is None:
|
|
initial = InitialConditionsWindow(
|
|
study = self._study,
|
|
config = self.conf,
|
|
parent = self
|
|
)
|
|
initial.show()
|
|
else:
|
|
initial.activateWindow()
|
|
else:
|
|
self.msg_select_reach()
|
|
|
|
def open_solver_parameters(self):
|
|
params = self.sub_win_filter_first(
|
|
"Solver parameters",
|
|
contain = []
|
|
)
|
|
|
|
if params is None:
|
|
params = SolverParametersWindow(
|
|
study = self._study,
|
|
parent = self
|
|
)
|
|
params.show()
|
|
else:
|
|
params.activateWindow()
|
|
|
|
def open_sediment_layers(self):
|
|
sl = SedimentLayersWindow(
|
|
study = self._study,
|
|
parent = self
|
|
)
|
|
sl.show()
|
|
|
|
def open_reach_sediment_layers(self):
|
|
sl = ReachSedimentLayersWindow(
|
|
study = self._study,
|
|
parent = self
|
|
)
|
|
sl.show()
|
|
|
|
def run_solver(self):
|
|
if self._study is None:
|
|
return
|
|
|
|
run = SelectSolverWindow(
|
|
study = self._study,
|
|
config = self.conf,
|
|
parent = self
|
|
)
|
|
if run.exec():
|
|
solver = run.solver
|
|
check = CheckListWindow(
|
|
study = self._study,
|
|
config = self.conf,
|
|
solver = solver,
|
|
parent = self
|
|
)
|
|
check.show()
|
|
|
|
def solver_log(self, solver):
|
|
sol = SolverLogWindow(
|
|
study = self._study,
|
|
config = self.conf,
|
|
solver = solver,
|
|
parent = self
|
|
)
|
|
sol.show()
|
|
|
|
def open_solver_results(self, solver, results = None):
|
|
# If no specific results, get last results
|
|
if results is None:
|
|
results = self._last_results
|
|
|
|
# No results available
|
|
if results is None:
|
|
return
|
|
|
|
# Windows already opened
|
|
res = self.sub_win_filter_first(
|
|
"Results",
|
|
contain = [solver.name, results.date]
|
|
)
|
|
|
|
if res is None:
|
|
res = ResultsWindow(
|
|
study = self._study,
|
|
solver = solver,
|
|
results = results,
|
|
parent = self
|
|
)
|
|
res.show()
|
|
else:
|
|
res.activateWindow()
|
|
|
|
def open_last_results(self):
|
|
if self._last_solver is None or self._last_results is None:
|
|
return
|
|
|
|
self.open_solver_results(self._last_solver, self._last_results)
|
|
|
|
def open_doc(self, filename):
|
|
doc = DocWindow(
|
|
filename = filename,
|
|
parent = self
|
|
)
|
|
doc.show()
|
|
|
|
|
|
def open_doc_user(self):
|
|
self.open_doc("Pamhyr2-users.html")
|
|
|
|
def open_doc_dev(self):
|
|
self.open_doc("Pamhyr2-dev.html")
|
|
|
|
#########
|
|
# DEBUG #
|
|
#########
|
|
|
|
def open_debug(self):
|
|
repl = ReplWindow(
|
|
study = self._study,
|
|
config = self.conf,
|
|
parent = self
|
|
)
|
|
repl.show()
|
|
|
|
def open_sqlite(self):
|
|
if self._study is None:
|
|
logger.debug("No study open for sql debuging...")
|
|
return
|
|
|
|
file = self._study.filename
|
|
_ = subprocess.Popen(
|
|
f"sqlitebrowser {file}",
|
|
shell=True
|
|
)
|
|
|
|
# TODO: Delete me !
|
|
###############
|
|
# DUMMY STUFF #
|
|
###############
|
|
|
|
def open_dummy(self, title="Dummy"):
|
|
self.dummy = DummyWindow(
|
|
title=title if type(title) is str else "Dummy",
|
|
parent=self
|
|
)
|
|
self.dummy.show()
|