diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py
index 905b2701..e2d52da0 100644
--- a/src/Model/Geometry/ProfileXYZ.py
+++ b/src/Model/Geometry/ProfileXYZ.py
@@ -58,7 +58,8 @@ class ProfileXYZ(Profile, SQLSubModel):
num=0,
nb_point: int = 0,
code1: int = 0, code2: int = 0,
- status=None, owner_scenario=-1):
+ status=None, owner_scenario=-1,
+ enabled=True):
"""ProfileXYZ constructor
Args:
@@ -90,6 +91,7 @@ class ProfileXYZ(Profile, SQLSubModel):
self.time_l = 0.0
self._station = []
self.station_up_to_date = False
+ self._enabled = bool(enabled)
self._get_water_limits_cache = {}
self._get_water_limits_ac_cache = {}
@@ -108,6 +110,7 @@ class ProfileXYZ(Profile, SQLSubModel):
code1 INTEGER NOT NULL,
code2 INTEGER NOT NULL,
sl INTEGER,
+ enabled BOOLEAN NOT NULL DEFAULT TRUE,
{Scenario.create_db_add_scenario()},
{Scenario.create_db_add_scenario_fk()},
FOREIGN KEY(reach) REFERENCES river_reach(pamhyr_id),
@@ -152,6 +155,13 @@ class ProfileXYZ(Profile, SQLSubModel):
"ADD COLUMN deleted BOOLEAN NOT NULL DEFAULT FALSE"
)
+ if major == "0" and int(minor) <=2:
+ if int(release) < 9:
+ execute(
+ "ALTER TABLE geometry_profileXYZ " +
+ "ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT TRUE"
+ )
+
return cls._update_submodel(execute, version, data)
@classmethod
@@ -237,7 +247,7 @@ class ProfileXYZ(Profile, SQLSubModel):
table = execute(
"SELECT pamhyr_id, ind, deleted, name, rk, num, " +
- "code1, code2, sl, scenario " +
+ "code1, code2, sl, scenario, enabled " +
"FROM geometry_profileXYZ " +
f"WHERE reach = {reach.id} " +
f"AND scenario = {scenario.id} " +
@@ -258,6 +268,7 @@ class ProfileXYZ(Profile, SQLSubModel):
code2 = next(it)
sl = next(it)
owner_scenario = next(it)
+ enabled = (next(it) == 1)
profile = cls(
id=pid, ind=ind, num=num,
@@ -265,7 +276,8 @@ class ProfileXYZ(Profile, SQLSubModel):
code1=code1, code2=code2,
reach=reach,
status=status,
- owner_scenario=owner_scenario
+ owner_scenario=owner_scenario,
+ enabled=enabled
)
if deleted:
profile.set_as_deleted()
@@ -318,12 +330,12 @@ class ProfileXYZ(Profile, SQLSubModel):
execute(
"INSERT OR REPLACE INTO " +
"geometry_profileXYZ(pamhyr_id, deleted, ind, name, reach, " +
- "rk, num, code1, code2, sl, scenario) " +
+ "rk, num, code1, code2, sl, scenario, enabled) " +
"VALUES (" +
f"{self.pamhyr_id}, {self._db_format(self.is_deleted())}, " +
f"{ind}, '{self._db_format(self._name)}', " +
f"{self.reach.pamhyr_id}, {self.rk}, {self.num}, " +
- f"{self.code1}, {self.code1}, {sl}, {self._status.scenario_id}" +
+ f"{self.code1}, {self.code1}, {sl}, {self._status.scenario_id}, {self._db_format(self._enabled)}" +
")"
)
@@ -390,7 +402,8 @@ class ProfileXYZ(Profile, SQLSubModel):
name=self.name,
rk=self.rk,
reach=self.reach,
- status=self._status
+ status=self._status,
+ enabled=self.is_enabled
)
if self.is_deleted():
new_p.set_as_deleted()
@@ -410,7 +423,8 @@ class ProfileXYZ(Profile, SQLSubModel):
name=self.name,
rk=self.rk,
reach=new_reach,
- status=self._status
+ status=self._status,
+ enabled=self.is_enabled
)
if self.is_deleted():
new_p.set_as_deleted()
@@ -1131,7 +1145,8 @@ class ProfileXYZ(Profile, SQLSubModel):
p = ProfileXYZ(name=self.name,
rk=self.rk,
reach=self.reach,
- status=self._status)
+ status=self._status,
+ enabled=self.is_enabled)
for i, k in enumerate(self.points):
p.insert_point(i, k.copy())
@@ -1165,3 +1180,16 @@ class ProfileXYZ(Profile, SQLSubModel):
break
self._points = points
self.modified()
+
+ @property
+ def is_enabled(self):
+ return self._enabled
+
+ @property
+ def enabled(self):
+ return self._enabled
+
+ @enabled.setter
+ def enabled(self, value):
+ self._enabled = bool(value)
+ self.modified()
diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py
index d2fea850..04f1144e 100644
--- a/src/Model/Geometry/Reach.py
+++ b/src/Model/Geometry/Reach.py
@@ -157,6 +157,14 @@ class Reach(SQLSubModel):
def profiles(self, profiles):
self._profiles = profiles
+ @property
+ def enabled_profiles(self):
+ return list(filter(lambda p: p.is_enabled, self.profiles))
+
+ @property
+ def number_enabled_profiles(self):
+ return len(self.enabled_profiles)
+
def get_profiles_from_rk(self, rk):
return list(
filter(
diff --git a/src/Model/Study.py b/src/Model/Study.py
index ded212ba..de86b428 100644
--- a/src/Model/Study.py
+++ b/src/Model/Study.py
@@ -46,7 +46,7 @@ logger = logging.getLogger()
class Study(SQLModel):
- _version = "0.2.7"
+ _version = "0.2.9"
_sub_classes = [
Scenario,
diff --git a/src/View/Geometry/Table.py b/src/View/Geometry/Table.py
index 847722d9..20b8ac01 100644
--- a/src/View/Geometry/Table.py
+++ b/src/View/Geometry/Table.py
@@ -64,15 +64,20 @@ class GeometryReachTableModel(PamhyrTableModel):
if not index.isValid():
return QVariant()
+ profile = self._data.profile(index.row())
+
+ if role == Qt.BackgroundRole and not profile.is_enabled:
+ return QColor(190, 190, 190)
+
if role == Qt.DisplayRole and index.column() == 0:
- return self._data.profile(index.row()).name
+ return profile.name
if role == Qt.DisplayRole and index.column() == 1:
- rk = self._data.profile(index.row()).rk
+ rk = profile.rk
return f"{rk:.4f}"
if role == Qt.DisplayRole and index.column() == 2:
- return str(self._data.profile(index.row()).nb_points)
+ return str(profile.nb_points)
if role == Qt.TextAlignmentRole:
return Qt.AlignHCenter | Qt.AlignVCenter
@@ -155,6 +160,14 @@ class GeometryReachTableModel(PamhyrTableModel):
self.endRemoveRows()
self.layoutChanged.emit()
+ def enabled(self, rows, enabled):
+ self._undo.push(
+ SetEnabledCommand(
+ self._data, rows, enabled
+ )
+ )
+ self.layoutChanged.emit()
+
def sort_profiles(self, _reverse):
self.layoutAboutToBeChanged.emit()
diff --git a/src/View/Geometry/Translate.py b/src/View/Geometry/Translate.py
index 1b3702da..c7e74e62 100644
--- a/src/View/Geometry/Translate.py
+++ b/src/View/Geometry/Translate.py
@@ -44,6 +44,9 @@ class GeometryTranslate(MainTranslate):
self._dict["cross_sections"] = _translate("Geometry", "cross-sections")
self._dict["profile"] = _translate("Geometry", "cross-section")
self._dict["profiles"] = _translate("Geometry", "cross-sections")
+ self._dict["cross_section_enabled_count"] = _translate(
+ "Geometry", "Cross-section enabled ({count} disabled)"
+ )
self._dict["transverse_abscissa"] = _translate(
"Geometry", "Transverse abscissa (m)"
diff --git a/src/View/Geometry/UndoCommand.py b/src/View/Geometry/UndoCommand.py
index 71e9c313..f14bfef8 100644
--- a/src/View/Geometry/UndoCommand.py
+++ b/src/View/Geometry/UndoCommand.py
@@ -68,6 +68,27 @@ class SetRKCommand(SetDataCommand):
self._reach.profile(self._index).rk = self._new
+class SetEnabledCommand(QUndoCommand):
+ def __init__(self, reach, rows, enabled):
+ QUndoCommand.__init__(self)
+
+ self._profiles = [reach.profile(row) for row in rows]
+ self._old = [profile.is_enabled for profile in self._profiles]
+ self._new = bool(enabled)
+
+ @staticmethod
+ def _set_enabled(profile, enabled):
+ profile.enabled = enabled
+
+ def undo(self):
+ for profile, enabled in zip(self._profiles, self._old):
+ self._set_enabled(profile, enabled)
+
+ def redo(self):
+ for profile in self._profiles:
+ self._set_enabled(profile, self._new)
+
+
class AddCommand(QUndoCommand):
def __init__(self, reach, index):
QUndoCommand.__init__(self)
diff --git a/src/View/Geometry/Window.py b/src/View/Geometry/Window.py
index 19e84363..f96121ca 100644
--- a/src/View/Geometry/Window.py
+++ b/src/View/Geometry/Window.py
@@ -99,6 +99,7 @@ class GeometryWindow(PamhyrWindow):
self._profile_window = []
self.setup_table()
+ self.setup_checkbox()
self.setup_plots()
self.setup_statusbar()
self.setup_connections()
@@ -124,6 +125,10 @@ class GeometryWindow(PamhyrWindow):
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.setAlternatingRowColors(True)
+ def setup_checkbox(self):
+ self._checkbox = self.find(QCheckBox, "checkBox_enabled")
+ self._set_checkbox_state()
+
def setup_plots(self):
self.setup_plots_xy()
self.setup_plots_rkc()
@@ -223,6 +228,9 @@ class GeometryWindow(PamhyrWindow):
.selectionChanged\
.connect(self.select_current_profile)
+ if not self._study.is_read_only():
+ self._checkbox.clicked.connect(self._set_profiles_state)
+
self._table.layoutChanged.connect(self.update_redraw)
def update(self):
@@ -525,6 +533,48 @@ class GeometryWindow(PamhyrWindow):
self._plot_ac.draw()
self.tableView.model().blockSignals(False)
+ self._set_checkbox_state()
+
+ def index_selected_rows(self):
+ return [
+ index.row()
+ for index in self.tableView.selectionModel().selectedRows()
+ ]
+
+ def _set_checkbox_state(self):
+ rows = self.index_selected_rows()
+ editable = not self._study.is_read_only()
+ disabled_count = self._reach.number_profiles - self._reach.number_enabled_profiles
+ self._checkbox.setText(
+ self._trad["cross_section_enabled_count"].format(
+ count=disabled_count
+ )
+ )
+
+ self._checkbox.setEnabled(editable and len(rows) > 0)
+ if len(rows) == 0:
+ self._checkbox.setTristate(False)
+ self._checkbox.setChecked(False)
+ return
+
+ states = {
+ self._reach.profile(row).is_enabled
+ for row in rows
+ }
+ if len(states) == 1:
+ self._checkbox.setTristate(False)
+ self._checkbox.setChecked(states.pop())
+ else:
+ self._checkbox.setTristate(True)
+ self._checkbox.setCheckState(Qt.PartiallyChecked)
+
+ def _set_profiles_state(self, enabled):
+ rows = self.index_selected_rows()
+ if len(rows) == 0:
+ return
+
+ self._checkbox.setTristate(False)
+ self._table.enabled(rows, enabled)
def add(self):
if len(self.tableView.selectedIndexes()) == 0:
diff --git a/src/View/ui/GeometryReach.ui b/src/View/ui/GeometryReach.ui
index 8c80a7bf..c87ed1db 100644
--- a/src/View/ui/GeometryReach.ui
+++ b/src/View/ui/GeometryReach.ui
@@ -24,10 +24,20 @@
Qt::Horizontal
-
+
-
+ -
+
+
+ Cross-section enabled (0 disabled)
+
+
+ true
+
+
+