Compare commits

..

7 Commits

23 changed files with 326 additions and 30 deletions

View File

@ -400,6 +400,16 @@ class BoundaryCondition(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for el in self._data:
el._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len( return len(
list( list(

View File

@ -415,6 +415,16 @@ class BoundaryConditionAdisTS(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)

View File

@ -197,6 +197,16 @@ class D90AdisTS(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)

View File

@ -220,6 +220,16 @@ class DIFAdisTS(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)

View File

@ -229,6 +229,16 @@ class BasicHS(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)

View File

@ -327,6 +327,16 @@ class HydraulicStructure(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self.lst) return len(self.lst)

View File

@ -374,6 +374,16 @@ class InitialConditions(SQLSubModel):
return ok return ok
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self.data) return len(self.data)

View File

@ -439,6 +439,17 @@ class LateralContribution(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len( return len(
list( list(

View File

@ -392,6 +392,16 @@ class LateralContributionAdisTS(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len( return len(
list( list(

View File

@ -441,6 +441,16 @@ class Pollutants(SQLSubModel):
return ok return ok
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
@property @property
def enabled(self): def enabled(self):
return self._enabled return self._enabled

View File

@ -375,6 +375,16 @@ class Reservoir(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for d in self._data:
d._data_traversal(predicate, modifier, data)
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)

View File

@ -627,6 +627,52 @@ class River(Graph):
except Exception as e: except Exception as e:
logger_exception(e) logger_exception(e)
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args:
predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns:
Nothing
"""
if predicate(self, data):
modifier(self, data)
for obj in self._get_objs_list():
obj._data_traversal(predicate, modifier, data)
def _get_objs_list(self):
objs = (self._nodes + self._edges)
objs += [
self._boundary_condition,
self._initial_conditions,
self._lateral_contribution,
self._sediment_layers,
self._stricklers,
self._reservoir,
self._hydraulic_structures,
self._additional_files,
self._rep_lines,
self._Output_rk_adists,
self._Pollutants,
self._InitialConditionsAdisTS,
self._BoundaryConditionsAdisTS,
self._LateralContributionsAdisTS,
self._D90AdisTS, self._DIFAdisTS,
]
for solver in self._parameters:
objs.append(self._parameters[solver])
return objs
def init_default(self): def init_default(self):
self.init_default_network() self.init_default_network()
self.init_default_sediment() self.init_default_sediment()

View File

@ -471,6 +471,16 @@ class SedimentLayer(SQLSubModel):
return True return True
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
if predicate(self, data):
modifier(self, data)
for layer in self._layers:
layer._data_traversal(predicate, modifier, data)
def get(self, index): def get(self, index):
return self.layers[index] return self.layers[index]

View File

@ -502,3 +502,25 @@ class Study(SQLModel):
self.status.set_as_read_only() self.status.set_as_read_only()
else: else:
self.status.set_as_editable() self.status.set_as_editable()
def duplicate_current_scenario(self):
source = self.status.scenario_id
new = self.scenarios.new(
self.status.scenario.parent
)
new.set_pos(self.status.scenario.x + 100,
self.status.scenario.y + 100)
new.name = self.status.scenario.name + " (copy)"
self.river._data_traversal(
predicate=lambda obj, data: obj._owner_scenario == source,
modifier=lambda obj, data: obj.set_owner_scenario(),
data={}
)
self.status.scenario = new
self.status.set_as_editable()
return new

View File

@ -202,7 +202,7 @@ class SQLSubModel(PamhyrID):
self._owner_scenario = self._status.scenario_id self._owner_scenario = self._status.scenario_id
self._status.modified() self._status.modified()
def set_owner_scenario_if(self, predicate): def set_owner_scenario(self):
"""Set study status the object owner_scenario to current """Set study status the object owner_scenario to current
scenario if predicate(scenario_id) is true scenario if predicate(scenario_id) is true
@ -215,9 +215,8 @@ class SQLSubModel(PamhyrID):
if self._status is None: if self._status is None:
return return
if predicate(self._owner_scenario): self._owner_scenario = self._status.scenario_id
self._owner_scenario = self._status.scenario_id self._status.modified()
self._status.modified()
def is_deleted(self): def is_deleted(self):
"""This object is deleted? """This object is deleted?
@ -414,3 +413,22 @@ class SQLSubModel(PamhyrID):
save save
""" """
raise NotImplementedMethodeError(self, self._db_save) raise NotImplementedMethodeError(self, self._db_save)
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args:
predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns:
Nothing
"""
if predicate(self, data):
modifier(self, data)

View File

@ -82,20 +82,24 @@ class PamhyrModelDict(SQLSubModel):
self.set(key, new) self.set(key, new)
return new return new
def rec_set_owner_scenario_if(self, predicate): def _data_traversal(self,
"""Set study status the object owner_scenario to current predicate=lambda obj, data: True,
scenario if predicate(scenario_id) is true modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args: Args:
predicate: Function predicate on owner_scenario id predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns: Returns:
Nothing Nothing
"""
self.set_owner_scenario_if(predicate)
for k in self._lst: """
self._dict[key].set_owner_scenario_if(predicate) for key in self._dict:
self._dict[key]\
._data_traversal(predicate, modifier, data)
def new(self, key): def new(self, key):
raise NotImplementedMethodeError(self, self.new) raise NotImplementedMethodeError(self, self.new)

View File

@ -85,20 +85,23 @@ class PamhyrModelList(SQLSubModel):
if self._status is not None: if self._status is not None:
self._status.modified() self._status.modified()
def rec_set_owner_scenario_if(self, predicate): def _data_traversal(self,
"""Set study status the object owner_scenario to current predicate=lambda obj, data: True,
scenario if predicate(scenario_id) is true modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args: Args:
predicate: Function predicate on owner_scenario id predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns: Returns:
Nothing Nothing
"""
self.set_owner_scenario_if(predicate)
"""
for el in self._lst: for el in self._lst:
el.set_owner_scenario_if(predicate) el._data_traversal(predicate, modifier, data)
def new(self, index): def new(self, index):
"""Create new elements and add it to list """Create new elements and add it to list
@ -210,6 +213,24 @@ class PamhyrModelListWithTab(SQLSubModel):
def _db_save(self, execute, data=None): def _db_save(self, execute, data=None):
raise NotImplementedMethodeError(self, self._db_save) raise NotImplementedMethodeError(self, self._db_save)
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args:
predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns:
Nothing
"""
for tab in self._tabs:
for el in self._tabs[tab]:
el._data_traversal(predicate, modifier, data)
################ ################
# MODEL METHOD # # MODEL METHOD #
################ ################

View File

@ -90,20 +90,22 @@ class PamhyrModelList(SQLSubModel):
if self._status is not None: if self._status is not None:
self._status.modified() self._status.modified()
def rec_set_owner_scenario_if(self, predicate): def _data_traversal(self,
"""Set study status the object owner_scenario to current predicate=lambda obj, data: True,
scenario if predicate(scenario_id) is true modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args: Args:
predicate: Function predicate on owner_scenario id predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns: Returns:
Nothing Nothing
""" """
self.set_owner_scenario_if(predicate)
for el in self._lst: for el in self._lst:
el.set_owner_scenario_if(predicate) el._data_traversal(predicate, modifier, data)
def new(self, index): def new(self, index):
"""Create new elements and add it to list """Create new elements and add it to list
@ -224,6 +226,24 @@ class PamhyrModelListWithTab(SQLSubModel):
def _db_save(self, execute, data=None): def _db_save(self, execute, data=None):
raise NotImplementedMethodeError(self, self._db_save) raise NotImplementedMethodeError(self, self._db_save)
def _data_traversal(self,
predicate=lambda obj, data: True,
modifier=lambda obj, data: None,
data={}):
"""Traversal data and execute modifier fonction if predicate
true
Args:
predicate: Function predicate, take current obj and data as input
modifier: Function modifier, take current obj and data as input
Returns:
Nothing
"""
for tab in self._tabs_list:
for el in self._tabs[tab]:
el._data_traversal(predicate, modifier, data)
################ ################
# MODEL METHOD # # MODEL METHOD #
################ ################

View File

@ -133,7 +133,7 @@ class Rubar3(CommandLineSolver):
def log_file(self): def log_file(self):
name = self._study.name name = self._study.name
return f"{name}" return f"geomac-i.{name}"
def export(self, study, repertory, qlog=None): def export(self, study, repertory, qlog=None):
self._study = study self._study = study

View File

@ -57,14 +57,23 @@ class DefaultMenu(AbstractMenu):
class ScenarioMenu(AbstractMenu): class ScenarioMenu(AbstractMenu):
def run(self): def run(self):
item = self._items[0] item = self._items[0]
current_scenario = item.graph._study.status.scenario.id
select = self._menu.addAction(self._trad["menu_select_scenario"]) select = self._menu.addAction(self._trad["menu_select_scenario"])
duplicate = None
delete = None
if item.scenario.id != 0: if item.scenario.id != 0:
delete = self._menu.addAction(self._trad["menu_del_scenario"]) delete = self._menu.addAction(self._trad["menu_del_scenario"])
if item.scenario.id == current_scenario:
duplicate = self._menu.addAction(
self._trad["menu_dup_scenario"]
)
action = self._exec() action = self._exec()
if action == select: if action == select:
self._parent.select_scenario(item) self._parent.select_scenario(item)
elif item.scenario.id != 0: elif action == delete:
if action == delete: self._parent.delete_scenario(item)
self._parent.delete_scenario(item) elif action == duplicate:
self._parent.duplicate_scenario(item)

View File

@ -459,6 +459,19 @@ class GraphWidget(QGraphicsView):
self.exec_with_waiting_window(fn, "delete_scenario") self.exec_with_waiting_window(fn, "delete_scenario")
self.changeScenario.emit(self.sender()) self.changeScenario.emit(self.sender())
def duplicate_scenario(self, item):
def fn():
self._close_other_window()
# self._study.save()
self._undo.push(
DuplicateScenariosCommand(
self._study,
)
)
self.exec_with_waiting_window(fn, "duplicate_scenario")
self.changeScenario.emit(self.sender())
def _close_other_window(self): def _close_other_window(self):
self.parent\ self.parent\
.parent\ .parent\

View File

@ -80,6 +80,25 @@ class DeleteScenariosCommand(QUndoCommand):
self._scenario.set_as_deleted() self._scenario.set_as_deleted()
class DuplicateScenariosCommand(QUndoCommand):
def __init__(self, study):
QUndoCommand.__init__(self)
self._study = study
self._new = None
def undo(self):
self._study.scenarios.delete(self._new.id)
self._study.reload_from_scenario(self._new.parent)
def redo(self):
if self._new is None:
self._new = self._study.duplicate_current_scenario()
else:
self._new.set_as_not_deleted()
self._study.reload_from_scenario(self._new)
class SetCommand(QUndoCommand): class SetCommand(QUndoCommand):
def __init__(self, scenario, column, new_value): def __init__(self, scenario, column, new_value):
QUndoCommand.__init__(self) QUndoCommand.__init__(self)

View File

@ -40,6 +40,9 @@ class ScenariosTranslate(MainTranslate):
self._dict["menu_del_scenario"] = _translate( self._dict["menu_del_scenario"] = _translate(
"Scenarios", "Delete this scenario" "Scenarios", "Delete this scenario"
) )
self._dict["menu_dup_scenario"] = _translate(
"Scenarios", "Duplicate this scenario"
)
self._sub_dict["table_headers_scenarios"] = { self._sub_dict["table_headers_scenarios"] = {
# "id": self._dict['id'], # "id": self._dict['id'],