diff --git a/src/Model/HydraulicStructures/Basic/HydraulicStructures.py b/src/Model/HydraulicStructures/Basic/HydraulicStructures.py index fcffeddf..b84f22b5 100644 --- a/src/Model/HydraulicStructures/Basic/HydraulicStructures.py +++ b/src/Model/HydraulicStructures/Basic/HydraulicStructures.py @@ -277,3 +277,10 @@ class BasicHS(SQLSubModel): def convert(self, new_type): return new_type(id=self.id, name=self.name, status=self._status) + + def cloned(self): + new = type(self)(name=self._name, status=self._status) + new._enabled = self._enabled + new._data = [value.cloned() for value in self._data] + new.modified() + return new diff --git a/src/Model/HydraulicStructures/Basic/Value.py b/src/Model/HydraulicStructures/Basic/Value.py index bdf03de5..907a81c7 100644 --- a/src/Model/HydraulicStructures/Basic/Value.py +++ b/src/Model/HydraulicStructures/Basic/Value.py @@ -208,3 +208,11 @@ class BHSValue(SQLSubModel): def value(self, value): self._value = self._type(value) self.modified() + + def cloned(self): + return BHSValue( + name=self._name, + type=self._type, + value=self._value, + status=self._status + ) diff --git a/src/Model/HydraulicStructures/HydraulicStructures.py b/src/Model/HydraulicStructures/HydraulicStructures.py index f07150c5..e3ed5155 100644 --- a/src/Model/HydraulicStructures/HydraulicStructures.py +++ b/src/Model/HydraulicStructures/HydraulicStructures.py @@ -427,6 +427,18 @@ class HydraulicStructure(SQLSubModel): def basic_structures(self): return self.lst.copy() + def cloned_for(self, input_reach, input_section, + output_reach, output_section): + new = HydraulicStructure(name=self._name, status=self._status) + new._enabled = self._enabled + new._input_reach = input_reach + new._input_section = input_section + new._output_reach = output_reach + new._output_section = output_section + new._data = [structure.cloned() for structure in self.lst] + new.modified() + return new + def basic_structure(self, index: int): if len(self._data) == 0: return None diff --git a/src/Model/HydraulicStructures/HydraulicStructuresList.py b/src/Model/HydraulicStructures/HydraulicStructuresList.py index 1c66dabf..2d1b347c 100644 --- a/src/Model/HydraulicStructures/HydraulicStructuresList.py +++ b/src/Model/HydraulicStructures/HydraulicStructuresList.py @@ -61,6 +61,71 @@ class HydraulicStructureList(PamhyrModelList): self.modified() return n + def split_reach(self, reach, profile, reach1, reach2): + profiles = reach.reach.profiles + split_index = profiles.index(profile) + sections1 = dict(zip( + profiles[:split_index + 1], + reach1.reach.profiles + )) + sections2 = dict(zip( + profiles[split_index:], + reach2.reach.profiles + )) + + def split_endpoint(endpoint_reach, section): + if endpoint_reach is not reach: + return endpoint_reach, section + if section not in profiles: + return endpoint_reach, section + + index = profiles.index(section) + if index < split_index: + return reach1, sections1[section] + return reach2, sections2[section] + + structures = [ + structure + for structure in self.lst + if (structure.input_reach is reach or + structure.output_reach is reach) + ] + + for structure in structures: + input_reach, input_section = split_endpoint( + structure.input_reach, + structure.input_section + ) + output_reach, output_section = split_endpoint( + structure.output_reach, + structure.output_section + ) + self._lst.append(structure.cloned_for( + input_reach, + input_section, + output_reach, + output_section + )) + + if len(structures) != 0: + self.modified() + + @property + def enabled_reaches_list(self): + return [ + structure + for structure in self.lst + if (structure.input_reach is None or + (not structure.input_reach.is_deleted() and + structure.input_reach.is_enable())) + ] + + def get_for_enabled_reaches(self, index): + structures = self.enabled_reaches_list + if not 0 <= index < len(structures): + return None + return structures[index] + def __copy__(self): new = HydraulicStructureList() diff --git a/src/Model/River.py b/src/Model/River.py index a6643c3e..abfc2be5 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -985,5 +985,8 @@ Last export at: @date.""" self._lateral_contribution.split_reach( reach, profile, r1, r2 ) + self._hydraulic_structures.split_reach( + reach, profile, r1, r2 + ) return r1, r2 diff --git a/src/View/HydraulicStructures/Table.py b/src/View/HydraulicStructures/Table.py index 5947b9b0..13a3057e 100644 --- a/src/View/HydraulicStructures/Table.py +++ b/src/View/HydraulicStructures/Table.py @@ -61,7 +61,7 @@ class ComboBoxDelegate(QItemDelegate): val = [] if self._mode == "rk": reach = self._data.hydraulic_structures\ - .get(index.row())\ + .get_for_enabled_reaches(index.row())\ .input_reach if reach is not None: val = list( @@ -73,7 +73,7 @@ class ComboBoxDelegate(QItemDelegate): else: val = list( map( - lambda n: n.name, self._data.edges() + lambda n: n.name, self._data.enable_edges() ) ) @@ -94,7 +94,7 @@ class ComboBoxDelegate(QItemDelegate): if self._mode == "rk": reach = self._data.hydraulic_structures\ - .get(index.row())\ + .get_for_enabled_reaches(index.row())\ .input_reach profiles = list( filter( @@ -128,20 +128,22 @@ class TableModel(PamhyrTableModel): self._lst = self._data._hydraulic_structures def get_true_data_row(self, row): - hs = self._lst.get(row) + hs = self._lst.get_for_enabled_reaches(row) + if hs is None: + return len(self._lst.lst) return next( map( lambda e: e[0], filter( lambda e: e[1] == hs, - enumerate(self._lst._lst) + enumerate(self._lst.lst) ) ), 0 ) def rowCount(self, parent): - return len(self._lst) + return len(self._lst.enabled_reaches_list) def data(self, index, role): if role != Qt.ItemDataRole.DisplayRole: @@ -149,16 +151,17 @@ class TableModel(PamhyrTableModel): row = index.row() column = index.column() + structure = self._lst.get_for_enabled_reaches(row) if self._headers[column] == "name": - return self._lst.get(row).name + return structure.name elif self._headers[column] == "reach": - n = self._lst.get(row).input_reach + n = structure.input_reach if n is None: return self._trad['not_associated'] return n.name elif self._headers[column] == "rk": - n = self._lst.get(row).input_section + n = structure.input_section if n is None: return self._trad['not_associated'] return n.display_name() @@ -174,6 +177,7 @@ class TableModel(PamhyrTableModel): row = index.row() column = index.column() + row = self.get_true_data_row(row) na = self._trad['not_associated'] try: diff --git a/src/View/HydraulicStructures/Window.py b/src/View/HydraulicStructures/Window.py index 3cb4a126..734b1a65 100644 --- a/src/View/HydraulicStructures/Window.py +++ b/src/View/HydraulicStructures/Window.py @@ -220,7 +220,7 @@ class HydraulicStructuresWindow(PamhyrWindow): def add(self): rows = self.index_selected_rows() - if len(self._hs_lst) == 0 or len(rows) == 0: + if len(self._hs_lst.enabled_reaches_list) == 0 or len(rows) == 0: self._table.add(0) else: self._table.add(rows[0]) @@ -247,7 +247,7 @@ class HydraulicStructuresWindow(PamhyrWindow): def edit(self): rows = self.index_selected_rows() for row in rows: - data = self._hs_lst.get(row) + data = self._hs_lst.get_for_enabled_reaches(row) if self.sub_window_exists( BasicHydraulicStructuresWindow, @@ -269,7 +269,8 @@ class HydraulicStructuresWindow(PamhyrWindow): self._checkbox.setChecked(True) else: self._checkbox.setEnabled(True) - self._checkbox.setChecked(self._hs_lst.get(row).enabled) + structure = self._hs_lst.get_for_enabled_reaches(row) + self._checkbox.setChecked(structure.enabled) def _set_structure_state(self): rows = self.index_selected_rows() @@ -288,16 +289,18 @@ class HydraulicStructuresWindow(PamhyrWindow): def _update_clear_plot(self): rows = self.index_selected_rows() - if len(rows) == 0 or len(self._hs_lst) == 0: + if (len(rows) == 0 or + len(self._hs_lst.enabled_reaches_list) == 0): self._update_clear_all() return - reach = self._hs_lst.get(rows[0]).input_reach + structure = self._hs_lst.get_for_enabled_reaches(rows[0]) + reach = structure.input_reach if reach is not None: self.plot_rkc.set_reach(reach) self.plot_ac.set_reach(reach) - profile = self._hs_lst.get(rows[0]).input_section + profile = structure.input_section if profile is not None: profiles = reach.reach\ .get_profiles_from_rk(