Compare commits

..
5 Commits
18 changed files with 249 additions and 81 deletions

No files matched your search

@@ -222,3 +222,82 @@ class BoundaryConditionAdisTS(SQLSubModel):
@property @property
def data(self): def data(self):
return self._data.copy() return self._data.copy()
@property
def _default_0(self):
return self._types[0](0)
@property
def _default_1(self):
return self._types[1](0.0)
def new_from_data(self, header, data):
new_0 = self._default_0
new_1 = self._default_1
if len(header) != 0:
for i in [0, 1]:
for j in range(len(header)):
if self._header[i] == header[j]:
if i == 0:
new_0 = self._types[i](data[j].replace(",", "."))
else:
new_1 = self._types[i](data[j].replace(",", "."))
else:
new_0 = self._types[0](data[0].replace(",", "."))
new_1 = self._types[1](data[1].replace(",", "."))
return (new_0, new_1)
def add(self, index: int):
value = (self._default_0, self._default_1)
self._data.insert(index, value)
self._status.modified()
return value
def insert(self, index: int, value):
self._data.insert(index, value)
self._status.modified()
def delete_i(self, indexes):
self._data = list(
map(
lambda e: e[1],
filter(
lambda e: e[0] not in indexes,
enumerate(self.data)
)
)
)
self._status.modified()
def sort(self, _reverse=False, key=None):
if key is None:
self._data.sort(reverse=_reverse)
else:
self._data.sort(reverse=_reverse, key=key)
self._status.modified()
def index(self, bc):
self._data.index(bc)
def get_i(self, index):
return self.data[index]
def get_range(self, _range):
lst = []
for r in _range:
lst.append(r)
return lst
def _set_i_c_v(self, index, column, value):
v = list(self._data[index])
v[column] = self._types[column](value)
self._data[index] = tuple(v)
self._status.modified()
def set_i_0(self, index: int, value):
self._set_i_c_v(index, 0, value)
def set_i_1(self, index: int, value):
self._set_i_c_v(index, 1, value)
@@ -155,7 +155,6 @@ class HydraulicStructure(SQLSubModel):
return new return new
def _db_save(self, execute, data=None): def _db_save(self, execute, data=None):
print("save hs unit")
execute(f"DELETE FROM hydraulic_structures WHERE id = {self.id}") execute(f"DELETE FROM hydraulic_structures WHERE id = {self.id}")
input_reach_id = -1 input_reach_id = -1
+4 -4
View File
@@ -45,7 +45,10 @@ class Pollutants(SQLSubModel):
else: else:
self.id = id self.id = id
self._name = str(name) if name is None or name == "":
self.name = f"pol{self.id}"
else:
self._name = str(name)
self._enabled = True self._enabled = True
self._data = [] self._data = []
@@ -179,7 +182,6 @@ class Pollutants(SQLSubModel):
def new_from_data(self, data): def new_from_data(self, data):
print("from_data before : ", data)
try: try:
new = [int(data[0])] new = [int(data[0])]
new += [float(d) for d in data[1:]] new += [float(d) for d in data[1:]]
@@ -187,8 +189,6 @@ class Pollutants(SQLSubModel):
logger.error(e) logger.error(e)
new = None new = None
print("from_data after : ", new)
return new return new
def __len__(self): def __len__(self):
@@ -41,7 +41,7 @@ from PyQt5.QtWidgets import (
) )
from View.BoundaryConditionsAdisTS.Edit.UndoCommand import ( from View.BoundaryConditionsAdisTS.Edit.UndoCommand import (
AddCommand, DelCommand, SetDataCommand, AddCommand, DelCommand, SetDataCommand, PasteCommand, SortCommand,
) )
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
@@ -118,3 +118,40 @@ class TableModel(PamhyrTableModel):
) )
self.endRemoveRows() self.endRemoveRows()
def sort(self, _reverse, parent=QModelIndex()):
self.layoutAboutToBeChanged.emit()
self._undo.push(
SortCommand(
self._data, _reverse
)
)
self.layoutAboutToBeChanged.emit()
self.update()
def paste(self, row, header, data):
if len(data) == 0:
return
self.layoutAboutToBeChanged.emit()
self._undo.push(
PasteCommand(
self._data, row,
list(
map(
lambda d: self._data.new_from_data(header, d),
data
)
)
)
)
self.layoutAboutToBeChanged.emit()
self.update()
def update(self):
# self.auto_sort()
self.layoutChanged.emit()
@@ -38,29 +38,14 @@ class SetDataCommand(QUndoCommand):
self._data = data self._data = data
self._index = index self._index = index
self._column = column self._column = column
self._old = self._data._data[self._index][self._column] self._old = self._data.get_i(self._index)[self._column]
_type = self._data._types[self._column] self._new = new_value
self._new = _type(new_value)
def undo(self): def undo(self):
if self._column == 0: self._data._set_i_c_v(self._index, self._column, self._old)
self._data._data[self._index] = (
self._old, self._data._data[self._index][1]
)
else:
self._data._data[self._index] = (
self._data._data[self._index][0], self._old
)
def redo(self): def redo(self):
if self._column == 0: self._data._set_i_c_v(self._index, self._column, self._new)
self._data._data[self._index] = (
self._new, self._data._data[self._index][1]
)
else:
self._data._data[self._index] = (
self._data._data[self._index][0], self._new
)
class AddCommand(QUndoCommand): class AddCommand(QUndoCommand):
@@ -76,11 +61,11 @@ class AddCommand(QUndoCommand):
def redo(self): def redo(self):
if self._new is None: if self._new is None:
self._new = self._data._data.insert(self._index, ( self._new = self._data.insert(self._index, (
self._data._types[0](0), self._data._types[1](0.0) self._data._types[0](0), self._data._types[1](0.0)
)) ))
else: else:
self._data._data.insert(self._index, self._new) self._data.insert(self._index, self._new)
class DelCommand(QUndoCommand): class DelCommand(QUndoCommand):
@@ -97,8 +82,57 @@ class DelCommand(QUndoCommand):
def undo(self): def undo(self):
for row, el in self._bc: for row, el in self._bc:
self._data._data.insert(row, el) self._data.insert(row, el)
def redo(self): def redo(self):
for row in self._rows: self._data.delete_i(self._rows)
del self._data._data[row]
class PasteCommand(QUndoCommand):
def __init__(self, data, row, bcs):
QUndoCommand.__init__(self)
self._data = data
self._row = row
self._bcs = bcs
self._bcs.reverse()
def undo(self):
self._data.delete_i(
range(self._row, self._row + len(self._bcs))
)
def redo(self):
for bc in self._bcs:
self._data.insert(self._row, bc)
class SortCommand(QUndoCommand):
def __init__(self, data, _reverse):
QUndoCommand.__init__(self)
self._data = data
self._reverse = _reverse
self._old = self._data.data
self._indexes = None
def undo(self):
ll = self._data.data
self._data.sort(
key=lambda x: self._indexes[ll.index(x)]
)
def redo(self):
self._data.sort(
_reverse=self._reverse,
key=lambda x: x[0]
)
if self._indexes is None:
self._indexes = list(
map(
lambda p: self._old.index(p),
self._data.data
)
)
self._old = None
@@ -143,7 +143,7 @@ class EditBoundaryConditionWindow(PamhyrWindow):
def setup_connections(self): def setup_connections(self):
self.find(QAction, "action_add").triggered.connect(self.add) self.find(QAction, "action_add").triggered.connect(self.add)
self.find(QAction, "action_del").triggered.connect(self.delete) self.find(QAction, "action_del").triggered.connect(self.delete)
self.find(QAction, "action_sort").triggered.connect(self.sort)
self._table.dataChanged.connect(self.update) self._table.dataChanged.connect(self.update)
def update(self): def update(self):
@@ -200,6 +200,22 @@ class EditBoundaryConditionWindow(PamhyrWindow):
self.copyTableIntoClipboard(table) self.copyTableIntoClipboard(table)
def _paste(self):
header, data = self.parseClipboardTable()
logger.debug(f"paste: h:{header}, d:{data}")
if len(data) == 0:
return
row = 0
rows = self.index_selected_rows()
if len(rows) != 0:
row = rows[0]
self._table.paste(row, header, data)
self.plot.update()
def _undo(self): def _undo(self):
self._table.undo() self._table.undo()
self.plot.update() self.plot.update()
+10 -17
View File
@@ -119,17 +119,10 @@ class TableModel(PamhyrTableModel):
super(TableModel, self).__init__(trad=trad, **kwargs) super(TableModel, self).__init__(trad=trad, **kwargs)
def _setup_lst(self):
self._lst = self._bc_list.lst
def rowCount(self, parent): def rowCount(self, parent):
return len(self._lst) return len(self._bc_list)
def data(self, index, role): def data(self, index, role):
if len(self._lst) != 0:
data = self._lst
else:
data = []
if role != Qt.ItemDataRole.DisplayRole: if role != Qt.ItemDataRole.DisplayRole:
return QVariant() return QVariant()
@@ -138,12 +131,12 @@ class TableModel(PamhyrTableModel):
column = index.column() column = index.column()
if self._headers[column] == "type": if self._headers[column] == "type":
n = data[row].type n = self._bc_list.get(row).type
if n is None or n == "": if n is None or n == "":
return self._trad["not_associated"] return self._trad["not_associated"]
return n return n
elif self._headers[column] == "node": elif self._headers[column] == "node":
n = data[row].node n = self._bc_list.get(row).node
if n is None: if n is None:
return self._trad["not_associated"] return self._trad["not_associated"]
tmp = next(filter(lambda x: x.id == n, self._data._nodes), None) tmp = next(filter(lambda x: x.id == n, self._data._nodes), None)
@@ -152,7 +145,7 @@ class TableModel(PamhyrTableModel):
else: else:
return self._trad["not_associated"] return self._trad["not_associated"]
elif self._headers[column] == "pol": elif self._headers[column] == "pol":
n = data[row].pollutant n = self._bc_list.get(row).pollutant
if n is None or n == "not_associated" or n == "": if n is None or n == "not_associated" or n == "":
return self._trad["not_associated"] return self._trad["not_associated"]
tmp = next(filter(lambda x: x.id == n, tmp = next(filter(lambda x: x.id == n,
@@ -177,20 +170,20 @@ class TableModel(PamhyrTableModel):
if self._headers[column] == "type": if self._headers[column] == "type":
self._undo.push( self._undo.push(
SetTypeCommand( SetTypeCommand(
self._lst, row, value self._bc_list, row, value
) )
) )
elif self._headers[column] == "node": elif self._headers[column] == "node":
self._undo.push( self._undo.push(
SetNodeCommand( SetNodeCommand(
self._lst, row, self._data.node(value) self._bc_list, row, self._data.node(value)
) )
) )
elif self._headers[column] == "pol": elif self._headers[column] == "pol":
if value == self._trad["not_associated"]: if value == self._trad["not_associated"]:
self._undo.push( self._undo.push(
SetPolCommand( SetPolCommand(
self._lst, row, None self._bc_list, row, None
) )
) )
else: else:
@@ -199,7 +192,7 @@ class TableModel(PamhyrTableModel):
) )
self._undo.push( self._undo.push(
SetPolCommand( SetPolCommand(
self._lst, row, pol.id self._bc_list, row, pol.id
) )
) )
except Exception as e: except Exception as e:
@@ -214,7 +207,7 @@ class TableModel(PamhyrTableModel):
self._undo.push( self._undo.push(
AddCommand( AddCommand(
self._pollutant, self._bc_list, self._lst, row self._pollutant, self._bc_list, row
) )
) )
@@ -226,7 +219,7 @@ class TableModel(PamhyrTableModel):
self._undo.push( self._undo.push(
DelCommand( DelCommand(
self._lst, rows self._bc_list, rows
) )
) )
@@ -35,14 +35,14 @@ class SetNodeCommand(QUndoCommand):
self._bcs = bcs self._bcs = bcs
self._index = index self._index = index
self._old = self._bcs[self._index].node self._old = self._bcs.get(self._index).node
self._new = node.id self._new = node.id
def undo(self): def undo(self):
self._bcs[self._index].node = self._old self._bcs.get(self._index).node = self._old
def redo(self): def redo(self):
self._bcs[self._index].node = self._new self._bcs.get(self._index).node = self._new
class SetTypeCommand(QUndoCommand): class SetTypeCommand(QUndoCommand):
@@ -52,14 +52,14 @@ class SetTypeCommand(QUndoCommand):
self._bcs = bcs self._bcs = bcs
self._index = index self._index = index
self._type = _type self._type = _type
self._old = self._bcs[self._index].type self._old = self._bcs.get(self._index).type
self._new = self._type self._new = self._type
def undo(self): def undo(self):
self._bcs[self._index].type = self._old self._bcs.get(self._index).type = self._old
def redo(self): def redo(self):
self._bcs[self._index].type = self._new self._bcs.get(self._index).type = self._new
class SetPolCommand(QUndoCommand): class SetPolCommand(QUndoCommand):
@@ -68,32 +68,31 @@ class SetPolCommand(QUndoCommand):
self._bcs = bcs self._bcs = bcs
self._index = index self._index = index
self._old = self._bcs[self._index].pollutant self._old = self._bcs.get(self._index).pollutant
self._new = pollutant self._new = pollutant
def undo(self): def undo(self):
self._bcs[self._index].pollutant = self._old self._bcs.get(self._index).pollutant = self._old
def redo(self): def redo(self):
self._bcs[self._index].pollutant = self._new self._bcs.get(self._index).pollutant = self._new
class AddCommand(QUndoCommand): class AddCommand(QUndoCommand):
def __init__(self, pollutant, bcs_list, bcs, index): def __init__(self, pollutant, bcs, index):
QUndoCommand.__init__(self) QUndoCommand.__init__(self)
self._bcs = bcs self._bcs = bcs
self._bc_list = bcs_list
self._pollutant = pollutant self._pollutant = pollutant
self._index = index self._index = index
self._new = None self._new = None
def undo(self): def undo(self):
del self._bcs[self._index] self._bcs.delete_i([self._index])
def redo(self): def redo(self):
if self._new is None: if self._new is None:
self._new = self._bc_list.new(self._index, self._pollutant) self._new = self._bcs.new(self._index, self._pollutant)
else: else:
self._bcs.insert(self._index, self._new) self._bcs.insert(self._index, self._new)
@@ -107,7 +106,7 @@ class DelCommand(QUndoCommand):
self._bc = [] self._bc = []
for row in rows: for row in rows:
self._bc.append((row, self._bcs[row])) self._bc.append((row, self._bcs.get(row)))
self._bc.sort() self._bc.sort()
def undo(self): def undo(self):
@@ -115,5 +114,4 @@ class DelCommand(QUndoCommand):
self._bcs.insert(row, el) self._bcs.insert(row, el)
def redo(self): def redo(self):
for row in self._rows: self._bcs.delete_i(self._rows)
del self._bcs[row]
+4 -1
View File
@@ -180,7 +180,10 @@ class BoundaryConditionAdisTSWindow(PamhyrWindow):
def edit(self): def edit(self):
rows = self.index_selected_rows() rows = self.index_selected_rows()
for row in rows: for row in rows:
data = self._bcs.lst[row] data = self._bcs.get(row)
if data.node is None:
continue
if self.sub_window_exists( if self.sub_window_exists(
EditBoundaryConditionWindow, EditBoundaryConditionWindow,
-1
View File
@@ -175,7 +175,6 @@ class D90TableModel(PamhyrTableModel):
) )
) )
elif self._headers[column] == "reach": elif self._headers[column] == "reach":
print(self._river.edge(value).id)
self._undo.push( self._undo.push(
SetCommandSpec( SetCommandSpec(
self._lst, row, self._headers[column], self._lst, row, self._headers[column],
-2
View File
@@ -279,9 +279,7 @@ class D90AdisTSWindow(PamhyrWindow):
self._table_spec.add(rows[0]) self._table_spec.add(rows[0])
def delete(self): def delete(self):
print("del")
rows = self.index_selected_rows() rows = self.index_selected_rows()
if len(rows) == 0: if len(rows) == 0:
print("len 0")
return return
self._table_spec.delete(rows) self._table_spec.delete(rows)
-1
View File
@@ -276,7 +276,6 @@ class InitialConditionsWindow(PamhyrWindow):
if filename != "": if filename != "":
size = os.stat(filename).st_size size = os.stat(filename).st_size
# self._table.import_geometry(0, filename) # self._table.import_geometry(0, filename)
print(f"filename: {filename}")
self._import_from_file(filename) self._import_from_file(filename)
def _import_from_file(self, file_name): def _import_from_file(self, file_name):
@@ -194,7 +194,6 @@ class InitialConditionTableModel(PamhyrTableModel):
) )
) )
elif self._headers[column] == "reach": elif self._headers[column] == "reach":
print(self._river.edge(value).id)
self._undo.push( self._undo.push(
SetCommandSpec( SetCommandSpec(
self._lst, row, self._headers[column], self._lst, row, self._headers[column],
@@ -281,9 +281,7 @@ class InitialConditionsAdisTSWindow(PamhyrWindow):
self._table_spec.add(rows[0]) self._table_spec.add(rows[0])
def delete(self): def delete(self):
print("del")
rows = self.index_selected_rows() rows = self.index_selected_rows()
if len(rows) == 0: if len(rows) == 0:
print("len 0")
return return
self._table_spec.delete(rows) self._table_spec.delete(rows)
+9 -8
View File
@@ -348,10 +348,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
def closeEvent(self, event): def closeEvent(self, event):
if not self._close_question: if not self._close_question:
if self._study is not None and not self._study.is_saved: if self._study is not None and not self._study.is_saved:
if self.dialog_close(cancel=False): if self.dialog_close():
# PAMHYR is close correctly (no crash) # PAMHYR is close correctly (no crash)
self.conf.set_close_correctly() self.conf.set_close_correctly()
super(ApplicationWindow, self).closeEvent(event) super(ApplicationWindow, self).closeEvent(event)
else:
event.ignore()
else: else:
super(ApplicationWindow, self).closeEvent(event) super(ApplicationWindow, self).closeEvent(event)
@@ -531,7 +533,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
self.update() self.update()
def close_model(self): def close_model(self):
if not self.dialog_close(cancel=True): if not self.dialog_close():
return return
self._study = None self._study = None
@@ -833,21 +835,19 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
return file return file
def dialog_close(self, cancel=True): def dialog_close(self):
dlg = QMessageBox(self) dlg = QMessageBox(self)
dlg.setWindowTitle(self._trad["mb_close_title"]) dlg.setWindowTitle(self._trad["mb_close_title"])
dlg.setText(self._trad["mb_close_msg"]) dlg.setText(self._trad["mb_close_msg"])
opt = QMessageBox.Save | QMessageBox.Close opt = QMessageBox.Save | QMessageBox.Close
if cancel: opt |= QMessageBox.Cancel
opt |= QMessageBox.Cancel
dlg.setStandardButtons(opt) dlg.setStandardButtons(opt)
dlg.setIcon(QMessageBox.Warning) dlg.setIcon(QMessageBox.Warning)
dlg.button(QMessageBox.Save).setText(self._trad["Save"]) dlg.button(QMessageBox.Save).setText(self._trad["Save"])
dlg.button(QMessageBox.Close).setText(self._trad["Close"]) dlg.button(QMessageBox.Close).setText(self._trad["Close"])
if cancel: dlg.button(QMessageBox.Cancel).setText(self._trad["Cancel"])
dlg.button(QMessageBox.Cancel).setText(self._trad["Cancel"])
res = dlg.exec() res = dlg.exec()
@@ -1319,7 +1319,6 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
# self.conf.solvers)) # self.conf.solvers))
# solver = next(filter(lambda x: x.name == "AdisTS-WC", # solver = next(filter(lambda x: x.name == "AdisTS-WC",
# self.conf.solvers)) # self.conf.solvers))
# print(solver._type)
# self.run_solver(solver) # self.run_solver(solver)
run = SelectSolverWindowAdisTS( run = SelectSolverWindowAdisTS(
@@ -1578,6 +1577,8 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
if run.exec(): if run.exec():
results = self.diff_results(run.solver1, results = self.diff_results(run.solver1,
run.solver2) run.solver2)
else:
return
# At least one result not available # At least one result not available
if results is None: if results is None:
+2
View File
@@ -1285,8 +1285,10 @@ class CustomPlot(PamhyrPlot):
self.lines["wet_area"][0].set_ydata(d) self.lines["wet_area"][0].set_ydata(d)
self._current.set_visible(False)
self.canvas.axes.relim(visible_only=True) self.canvas.axes.relim(visible_only=True)
self.canvas.axes.autoscale_view() self.canvas.axes.autoscale_view()
self._current.set_visible(True)
def draw(self): def draw(self):
self.draw_static() self.draw_static()
+1 -1
View File
@@ -113,7 +113,7 @@
<action name="action_sort"> <action name="action_sort">
<property name="icon"> <property name="icon">
<iconset> <iconset>
<normaloff>ressources/sort_A-Z.png</normaloff>ressources/sort_A-Z.png</iconset> <normaloff>ressources/sort_1-9.png</normaloff>ressources/sort_1-9.png</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Sort</string> <string>Sort</string>
@@ -72,6 +72,7 @@
</attribute> </attribute>
<addaction name="action_add"/> <addaction name="action_add"/>
<addaction name="action_del"/> <addaction name="action_del"/>
<addaction name="action_sort"/>
</widget> </widget>
<action name="action_add"> <action name="action_add">
<property name="checkable"> <property name="checkable">
@@ -106,6 +107,18 @@
<string>Ctrl+D</string> <string>Ctrl+D</string>
</property> </property>
</action> </action>
<action name="action_sort">
<property name="icon">
<iconset>
<normaloff>ressources/sort_1-9.png</normaloff>ressources/sort_1-9.png</iconset>
</property>
<property name="text">
<string>Sort</string>
</property>
<property name="toolTip">
<string>Sort points</string>
</property>
</action>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>