Pamhyr2, Scenario: Add Read only mode.

scenarios
Pierre-Antoine Rouby 2024-09-03 15:22:02 +02:00
parent 8f0535dc5c
commit 8afa3d1e30
9 changed files with 103 additions and 17 deletions

View File

@ -18,12 +18,20 @@
import logging
from enum import Enum, auto
logger = logging.getLogger()
class Status(Enum):
EDIT = auto()
READ_ONLY = auto()
class StudyStatus(object):
def __init__(self, scenario=None):
super(StudyStatus, self).__init__()
self._status = Status.EDIT
self._scenario = scenario
self._saved = True
@ -34,6 +42,18 @@ class StudyStatus(object):
return self._scenario.id
def is_editable(self):
return self._status == Status.EDIT
def set_as_editable(self):
self._status = Status.EDIT
def is_read_only(self):
return self._status == Status.READ_ONLY
def set_as_read_only(self):
self._status = Status.READ_ONLY
@property
def scenario(self):
return self._scenario

View File

@ -22,6 +22,7 @@ import logging
from datetime import datetime
from tools import timer, timestamp
from functools import reduce
from Model.Tools.PamhyrDB import SQLModel
from Model.Scenarios import Scenarios
@ -94,6 +95,12 @@ class Study(SQLModel):
def river(self):
return self._river
def is_editable(self):
return self.status.is_editable()
def is_read_only(self):
return self.status.is_read_only()
@property
def is_saved(self):
return self.status.is_saved()
@ -354,6 +361,13 @@ class Study(SQLModel):
scenario = new.scenarios[int(scenario_id[0])]
new.status.scenario = scenario
if reduce(
lambda a, s: a or (s.parent is scenario),
new.scenarios.lst,
False
):
new.status.set_as_read_only()
data["scenario"] = scenario
data["loaded_pid"] = set()
@ -444,6 +458,7 @@ class Study(SQLModel):
if switch:
self.status.scenario = new
self.status.set_as_editable()
return new
def reload_from_scenario(self, scenario):
@ -464,3 +479,12 @@ class Study(SQLModel):
sql_exec,
data=data
)
if reduce(
lambda a, s: a or (s.parent is scenario),
self.scenarios.lst,
False
):
self.status.set_as_read_only()
else:
self.status.set_as_editable()

View File

@ -883,6 +883,9 @@ class GraphWidget(QGraphicsView):
super(GraphWidget, self).mousePressEvent(event)
return
if self.graph._status.is_read_only():
return
# Move item and select edge item
if self._state == "move":
self._selected_new_edge_src_node = None
@ -932,7 +935,7 @@ class GraphWidget(QGraphicsView):
def mouseReleaseEvent(self, event):
self.clicked = False
if self._only_display:
if self._only_display or self.graph._status.is_read_only():
return
if self._state == "move":
@ -951,6 +954,9 @@ class GraphWidget(QGraphicsView):
super(GraphWidget, self).mouseReleaseEvent(event)
def mouseMoveEvent(self, event):
if self.graph._status.is_read_only():
return
pos = self.mapToScene(event.pos())
# Selecte item on the fly
@ -1002,7 +1008,7 @@ class GraphWidget(QGraphicsView):
# Contextual menu
def contextMenuEvent(self, event):
if self._only_display:
if self._only_display or self.graph._status.is_read_only():
return
pos = self.mapToScene(event.pos())

View File

@ -85,11 +85,18 @@ class NetworkWindow(PamhyrWindow):
def setup_table(self):
# Nodes table
if self._study.is_read_only:
node_editable_headers = []
edge_editable_headers = []
else:
node_editable_headers = ["name"]
edge_editable_headers = ["name", "node1", "node2"]
table = self.find(QTableView, "tableView_nodes")
self._nodes_model = NodeTableModel(
table_view=table,
table_headers=self._table_headers_node,
editable_headers=["name"],
editable_headers=node_editable_headers,
data=self._graph,
undo=self._undo_stack,
)
@ -108,7 +115,7 @@ class NetworkWindow(PamhyrWindow):
self._reachs_model = EdgeTableModel(
table_view=table,
table_headers=self._table_headers_edge,
editable_headers=["name", "node1", "node2"],
editable_headers=edge_editable_headers,
delegates={
"node1": self.delegate_combobox,
"node2": self.delegate_combobox,
@ -132,22 +139,24 @@ class NetworkWindow(PamhyrWindow):
def setup_connections(self):
self._nodes_model.dataChanged.connect(self.update)
self._nodes_model.dataChanged.connect(self._graph_widget.rename_nodes)
self._reachs_model.dataChanged.connect(
self._graph_widget.display_update)
self._reachs_model.dataChanged.connect(self.update)
self._graph_widget.changeEdge.connect(self.update)
self._graph_widget.changeNode.connect(self.update)
self.find(QAction, "action_toolBar_add").setCheckable(True)
self.find(QAction, "action_toolBar_add").triggered.connect(
self.clicked_add
)
if self._study.is_editable:
self._nodes_model.dataChanged.connect(self._graph_widget.rename_nodes)
self.find(QAction, "action_toolBar_del").setCheckable(True)
self.find(QAction, "action_toolBar_del").triggered.connect(
self.clicked_del
)
self.find(QAction, "action_toolBar_add").setCheckable(True)
self.find(QAction, "action_toolBar_add").triggered.connect(
self.clicked_add
)
self.find(QAction, "action_toolBar_del").setCheckable(True)
self.find(QAction, "action_toolBar_del").triggered.connect(
self.clicked_del
)
def clicked_add(self):
if self.get_action_checkable("action_toolBar_add"):

View File

@ -61,7 +61,7 @@ class ScenarioItem(QGraphicsTextItem):
if self.graph.scenario_has_child(self.scenario):
tag = ""
self.setPlainText(tag + self.scenario.name)
self.setHtml(tag + self.scenario.name)
self.setDefaultTextColor(Qt.black)
self.setFlag(QGraphicsItem.ItemIsMovable)
@ -412,7 +412,9 @@ class GraphWidget(QGraphicsView):
self._study.save()
self._study.reload_from_scenario(item.scenario)
self._close_other_window()
self.exec_with_waiting_window(fn, "select_scenario")
self.changeScenario.emit(self.sender())
def new_scenario(self, pos):
@ -421,5 +423,14 @@ class GraphWidget(QGraphicsView):
scenario = self._study.new_scenario_from_current()
scenario.set_pos(pos.x(), pos.y())
self._close_other_window()
self.exec_with_waiting_window(fn, "new_scenario")
self.changeScenario.emit(self.sender())
def _close_other_window(self):
self.parent\
.parent\
._close_sub_window(
exceptions=["Scenarios", "Debug REPL"]
)

View File

@ -124,5 +124,6 @@ class ScenariosWindow(PamhyrWindow):
def update(self):
self._scenarios_model.update()
self._graph_widget.display_update()
self._set_title()
self._propagate_update(key=Modules.SCENARIOS)

View File

@ -39,7 +39,7 @@ class ScenariosTranslate(MainTranslate):
)
self._sub_dict["table_headers_scenarios"] = {
"id": self._dict['id'],
# "id": self._dict['id'],
"name": self._dict['name'],
"description": self._dict['description'],
"parent": _translate("Scenarios", "Parent"),

View File

@ -117,6 +117,9 @@ class ListedSubWindow(object):
except Exception:
return
def _close_sub_window(self):
for _, win in self._sub_win_list:
def _close_sub_window(self, exceptions=[]):
for name, win in self._sub_win_list:
if name in exceptions:
continue
win.close()

View File

@ -183,6 +183,18 @@ class PamhyrWindow(ASubMainWindow, ListedSubWindow, PamhyrWindowTools):
self._set_title()
self._set_icon()
def _set_title(self):
title = self._title
if self._study.is_read_only():
title = "" + title
scenario = self._study.status.scenario
if scenario is not None and scenario.name != "default":
title += f" | {scenario.name}"
self.ui.setWindowTitle(title)
def closeEvent(self, event):
self._close_sub_window()
self._propagate_update(Modules.WINDOW_LIST)