Pamhyr: Implement window duplication deny mechanism with hash (#7).

setup.py
Pierre-Antoine Rouby 2023-10-20 10:48:07 +02:00
parent 4c40f675b5
commit 8760cd364d
9 changed files with 186 additions and 122 deletions

View File

@ -68,6 +68,9 @@ class CheckListWindow(PamhyrWindow):
parent=parent parent=parent
) )
# Add solver to hash computation data
self._hash_data.append(self._solver)
self._checker_list = ( self._checker_list = (
self._study.checkers() + self._study.checkers() +
self._solver.checkers() self._solver.checkers()

View File

@ -83,6 +83,9 @@ class FrictionsWindow(PamhyrWindow):
parent=parent parent=parent
) )
# Add reach to hash computation data
self._hash_data.append(self._reach)
self.setup_table() self.setup_table()
self.setup_graph() self.setup_graph()
self.setup_connections() self.setup_connections()

View File

@ -73,6 +73,9 @@ class GeometryWindow(PamhyrWindow):
parent=parent parent=parent
) )
# Add reach to hash computation data
self._hash_data.append(self._reach)
self._tablemodel = None self._tablemodel = None
self._profile_window = [] self._profile_window = []

View File

@ -87,6 +87,9 @@ class InitialConditionsWindow(PamhyrWindow):
parent=parent parent=parent
) )
# Add reach to hash computation data
self._hash_data.append(self._reach)
self._ics = study.river.initial_conditions.get(self._reach) self._ics = study.river.initial_conditions.get(self._reach)
self.setup_table() self.setup_table()

View File

@ -480,6 +480,30 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
# SUBWINDOW # # SUBWINDOW #
############# #############
def _sub_window_exists(self, cls,
data=None):
"""Check if window already exists
Check if window already exists, used to deni window open
duplication
Args:
cls: Window class, must inerit to PamhyrWindow or
PamhyrDialog
data: Data used for hash computation of cls
Returns:
The window if hash already exists on sub window dictionary,
otherelse None
"""
hash = cls._hash(data)
if self.sub_win_exists(hash):
win = self.get_sub_win(hash)
win.activateWindow()
return True
else:
return False
def open_configure(self): def open_configure(self):
"""Open configure window """Open configure window
@ -488,6 +512,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Returns: Returns:
Nothing Nothing
""" """
if self._sub_window_exists(
ConfigureWindow,
data=[None, self.conf]
):
return
self.config = ConfigureWindow(config=self.conf, parent=self) self.config = ConfigureWindow(config=self.conf, parent=self)
self.config.show() self.config.show()
@ -499,6 +529,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Returns: Returns:
Nothing Nothing
""" """
if self._sub_window_exists(
AboutWindow,
data=[None, None]
):
return
self.about = AboutWindow(parent=self) self.about = AboutWindow(parent=self)
self.about.show() self.about.show()
@ -527,6 +563,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Nothing Nothing
""" """
if self._study is None: if self._study is None:
if self._sub_window_exists(
NewStudyWindow,
data=[None, None]
):
return
self.new_study = NewStudyWindow(parent=self) self.new_study = NewStudyWindow(parent=self)
self.new_study.show() self.new_study.show()
@ -537,6 +579,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Nothing Nothing
""" """
if self._study is not None: if self._study is not None:
if self._sub_window_exists(
NewStudyWindow,
data=[self._study, None]
):
return
self.new_study = NewStudyWindow(study=self._study, parent=self) self.new_study = NewStudyWindow(study=self._study, parent=self)
self.new_study.show() self.new_study.show()
@ -547,11 +595,14 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Nothing Nothing
""" """
if self._study is not None: if self._study is not None:
if not self.sub_win_exists("River network"): if self._sub_window_exists(
self.network = NetworkWindow(study=self._study, parent=self) NetworkWindow,
self.network.show() data=[self._study, None]
else: ):
self.network.activateWindow() return
self.network = NetworkWindow(study=self._study, parent=self)
self.network.show()
def open_geometry(self): def open_geometry(self):
"""Open geometry window """Open geometry window
@ -560,115 +611,117 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Nothing Nothing
""" """
if (self._study is not None and self._study.river.has_current_reach()): if (self._study is not None and self._study.river.has_current_reach()):
geometry = self.sub_win_filter_first( reach = self._study.river.current_reach().reach
"Geometry",
contain=[self._study.river.current_reach().name]
)
if geometry is None: if self._sub_window_exists(
geometry = GeometryWindow( GeometryWindow,
study=self._study, config=self.conf, parent=self) data=[self._study, self.conf, reach]
geometry.show() ):
else: return
geometry.activateWindow()
geometry = GeometryWindow(
study=self._study,
config=self.conf,
reach=reach,
parent=self
)
geometry.show()
else: else:
self.msg_select_reach() self.msg_select_reach()
def open_boundary_cond(self): def open_boundary_cond(self):
bound = self.sub_win_filter_first( if self._sub_window_exists(
"Boundary conditions", BoundaryConditionWindow,
contain=[] data=[self._study, None]
) ):
return
if bound is None: bound = BoundaryConditionWindow(study=self._study, parent=self)
bound = BoundaryConditionWindow(study=self._study, parent=self) bound.show()
bound.show()
else:
bound.activateWindow()
def open_lateral_contrib(self): def open_lateral_contrib(self):
lateral = self.sub_win_filter_first( if self._sub_window_exists(
"Lateral contribution", LateralContributionWindow,
contain=[] data=[self._study, None]
) ):
return
if lateral is None: lateral = LateralContributionWindow(study=self._study, parent=self)
lateral = LateralContributionWindow(study=self._study, parent=self) lateral.show()
lateral.show()
else:
lateral.activateWindow()
def open_stricklers(self): def open_stricklers(self):
strick = self.sub_win_filter_first( if self._sub_window_exists(
"Stricklers", StricklersWindow,
contain=[] data=[self._study, self.conf]
) ):
return
if strick is None: strick = StricklersWindow(
strick = StricklersWindow( study=self._study,
study=self._study, config=self.conf,
config=self.conf, parent=self
parent=self )
) strick.show()
strick.show()
else:
strick.activateWindow()
def open_frictions(self): def open_frictions(self):
if (self._study is not None and if self._study is not None:
self._study.river.has_current_reach()): if self._study.river.has_current_reach():
reach = self._study.river.current_reach()
frictions = self.sub_win_filter_first( if self._sub_window_exists(
"Frictions", FrictionsWindow,
contain=[self._study.river.current_reach().name] data=[self._study, None, reach]
) ):
return
if frictions is None:
frictions = FrictionsWindow( frictions = FrictionsWindow(
study=self._study, study=self._study,
parent=self parent=self
) )
frictions.show() frictions.show()
else: else:
frictions.activateWindow() self.msg_select_reach()
else:
self.msg_select_reach()
def open_initial_conditions(self): def open_initial_conditions(self):
if self._study.river.has_current_reach(): if self._study.river.has_current_reach():
initial = self.sub_win_filter_first( reach = self._study.river.current_reach()
"Initial condition",
contain=[self._study.river.current_reach().name]
)
if initial is None: if self._sub_window_exists(
initial = InitialConditionsWindow( InitialConditionsWindow,
study=self._study, data=[self._study, self.conf, reach]
config=self.conf, ):
parent=self return
)
initial.show() initial = InitialConditionsWindow(
else: study=self._study,
initial.activateWindow() config=self.conf,
reach=reach,
parent=self
)
initial.show()
else: else:
self.msg_select_reach() self.msg_select_reach()
def open_solver_parameters(self): def open_solver_parameters(self):
params = self.sub_win_filter_first( if self._sub_window_exists(
"Solver parameters", SolverParametersWindow,
contain=[] data=[self._study, None]
) ):
return
if params is None: params = SolverParametersWindow(
params = SolverParametersWindow( study=self._study,
study=self._study, parent=self
parent=self )
) params.show()
params.show()
else:
params.activateWindow()
def open_sediment_layers(self): def open_sediment_layers(self):
if self._sub_window_exists(
SedimentLayersWindow,
data=[self._study, None]
):
return
sl = SedimentLayersWindow( sl = SedimentLayersWindow(
study=self._study, study=self._study,
parent=self parent=self
@ -676,8 +729,17 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
sl.show() sl.show()
def open_reach_sediment_layers(self): def open_reach_sediment_layers(self):
reach = self._study.river.current_reach().reach
if self._sub_window_exists(
ReachSedimentLayersWindow,
data=[self._study, None, reach]
):
return
sl = ReachSedimentLayersWindow( sl = ReachSedimentLayersWindow(
study=self._study, study=self._study,
reach=reach,
parent=self parent=self
) )
sl.show() sl.show()
@ -693,6 +755,17 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
) )
if run.exec(): if run.exec():
solver = run.solver solver = run.solver
if self._sub_window_exists(
CheckListWindow,
data=[
self._study,
self.conf,
solver
]
):
return
check = CheckListWindow( check = CheckListWindow(
study=self._study, study=self._study,
config=self.conf, config=self.conf,

View File

@ -46,9 +46,12 @@ class ReachSedimentLayersWindow(PamhyrWindow):
_pamhyr_ui = "ReachSedimentLayers" _pamhyr_ui = "ReachSedimentLayers"
_pamhyr_name = "Reach sediment layers" _pamhyr_name = "Reach sediment layers"
def __init__(self, study=None, config=None, parent=None): def __init__(self, study=None, config=None, reach=None, parent=None):
self._sediment_layers = study.river.sediment_layers self._sediment_layers = study.river.sediment_layers
self._reach = study.river.current_reach().reach if reach is None:
self._reach = study.river.current_reach().reach
else:
self._reach = reach
name = ( name = (
self._pamhyr_name + " - " + self._pamhyr_name + " - " +
@ -64,6 +67,9 @@ class ReachSedimentLayersWindow(PamhyrWindow):
parent=parent parent=parent
) )
# Add reach to hash computation data
self._hash_data.append(self._reach)
self.setup_table() self.setup_table()
self.setup_plot() self.setup_plot()
self.setup_connections() self.setup_connections()

View File

@ -483,7 +483,7 @@ class ASubMainWindow(QMainWindow, ASubWindowFeatures, WindowToolKit):
def closeEvent(self, event): def closeEvent(self, event):
if self.parent is not None: if self.parent is not None:
self.parent.sub_win_del(self.name) self.parent.sub_win_del(self.hash())
def find(self, qtype, name): def find(self, qtype, name):
"""Find an ui component """Find an ui component
@ -520,7 +520,7 @@ class ASubWindow(QDialog, ASubWindowFeatures, WindowToolKit):
def closeEvent(self, event): def closeEvent(self, event):
if self.parent is not None: if self.parent is not None:
self.parent.sub_win_del(self.name) self.parent.sub_win_del(self.hash())
def find(self, qtype, name): def find(self, qtype, name):
"""Find an ui component """Find an ui component

View File

@ -42,59 +42,33 @@ class ListedSubWindow(object):
f"Open window: {name}: {self.sub_win_cnt}: {win.hash()}") f"Open window: {name}: {self.sub_win_cnt}: {win.hash()}")
except Exception: except Exception:
logger.info(f"Open window: {name}: {self.sub_win_cnt}: X") logger.info(f"Open window: {name}: {self.sub_win_cnt}: X")
logger.warning(f"Sub window without hash method !")
def sub_win_del(self, name): def sub_win_del(self, h):
self.sub_win_list = list( self.sub_win_list = list(
filter( filter(
lambda x: x[0] != name, lambda x: x[1].hash() != h,
self.sub_win_list self.sub_win_list
) )
) )
self.sub_win_cnt = len(self.sub_win_list) self.sub_win_cnt = len(self.sub_win_list)
logger.info(f"Close window: {name}: {self.sub_win_cnt}") logger.info(f"Close window: {h}: {self.sub_win_cnt}")
def _sub_win_exists(self, name): def _sub_win_exists(self, h):
return reduce( return reduce(
lambda acc, n: (acc or (n[0] == name)), lambda acc, el: (acc or (h == (el[1].hash()))),
self.sub_win_list, self.sub_win_list,
False False
) )
def _sub_win_exists_with_contain(self, name, contain): def sub_win_exists(self, h):
return reduce( return self._sub_win_exists(h)
lambda acc, n: (
acc or
(
(n[0] == name) and
reduce(
lambda acc, c: acc and (c in n[1]._title),
contain,
True
)
)
),
self.sub_win_list,
False
)
def sub_win_exists(self, name, contain=[]): def get_sub_win(self, h):
if contain == []:
return self._sub_win_exists(name)
else:
return self._sub_win_exists_with_contain(name, contain)
def sub_win_filter_first(self, name, contain):
try: try:
return next( return next(
filter( filter(
lambda n: ( lambda el: (h == el[1].hash()),
(name in n[0]) and
reduce(
lambda acc, c: acc and (c in n[1]._title),
contain,
True
)
),
self.sub_win_list, self.sub_win_list,
) )
)[1] )[1]

View File

@ -122,7 +122,6 @@ class PamhyrWindowTools(object):
hash_str += repr(el) hash_str += repr(el)
h = hash(hash_str) h = hash(hash_str)
logger.debug(f"Compute hash = {h} for window {cls._pamhyr_name}")
return h return h