Commit 6b1a77b2 authored by Pierre-Antoine Rouby's avatar Pierre-Antoine Rouby
Browse files

BC: Some change.

Showing with 526 additions and 48 deletions
+526 -48
# -*- coding: utf-8 -*-
from copy import copy
from Model.Except import NotImplementedMethodeError
class BoundaryConditionList(object):
def __init__(self):
self._data = []
def __len__(self):
return len(self._data)
def __getitem__(self, index):
return self._data[index]
def __setitem__(self, index, value):
self._data[index] = value
def __copy__(self):
new = BoundaryConditionList()
new._data = self._data.copy()
return new
def copy(self):
return copy(self)
class BoundaryCondition(object):
def __init__(self, name:str = ""):
super(BoundaryCondition, self).__init__()
......@@ -67,6 +44,12 @@ class BoundaryCondition(object):
def data(self):
return self._data.copy()
def _default_0(self):
return self._types[0](0)
def _default_1(self):
return self._types[1](0.0)
def is_define(self):
return self._data is not None
......@@ -117,9 +100,3 @@ class BoundaryCondition(object):
new._set_i_c_v(ind, j, v[i])
return new
def _default_0(self):
return self._types[0](0)
def _default_1(self):
return self._types[1](0.0)
# -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer
from Model.Except import NotImplementedMethodeError
from Model.BoundaryCondition.BoundaryConditionTypes import (
NotDefined,
PonctualContribution,
TimeOverZ, TimeOverDebit, ZOverDebit
)
class BoundaryConditionList(list):
def __init__(self):
super(BoundaryConditionList, self).__init__()
def new(self, index):
n = NotDefined()
self.insert(index, n)
return n
def delete(self, bcs):
for bc in bcs:
self.remove(bc)
def delete_i(self, indexes):
bcs = map(
lambda x: x[1],
filter(
lambda x: x[0] in indexes,
enumerate(self)
)
)
for bc in bcs:
self.remove(bc)
def move_up(self, index):
if index < len(self):
next = index - 1
self[index], self[next] = self[next], self[index]
def move_down(self, index):
if index >= 0:
prev = index + 1
self[index], self[prev] = self[prev], self[index]
def __copy__(self):
new = BoundaryConditionList()
for bc in self:
new.append(bc)
return new
def __deepcopy__(self):
new = BoundaryConditionList()
for bc in self:
new.append(deepcopy(bc))
return new
def copy(self):
return copy(self)
......@@ -4,12 +4,14 @@ from Model.Except import NotImplementedMethodeError
from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
BC_types = [
"PC",
"TZ",
"TD",
"ZD"
]
class NotDefined(BoundaryCondition):
def __init__(self, name:str = ""):
super(NotDefined, self).__init__(name=name)
self._type = "ND"
self._header = ["", ""]
self._types = [str, str]
class PonctualContribution(BoundaryCondition):
def __init__(self, name:str = ""):
......
......@@ -8,8 +8,10 @@ from Model.Geometry.Profile import Profile
from Model.Geometry.Reach import Reach
from Model.BoundaryCondition.BoundaryCondition import (
BoundaryCondition,
BoundaryConditionList,
BoundaryCondition
)
from Model.BoundaryCondition.BoundaryConditionList import (
BoundaryConditionList
)
......
# -*- coding: utf-8 -*-
from copy import deepcopy
from tools import trace, timer
from PyQt5.QtWidgets import (
QMessageBox, QUndoCommand, QUndoStack,
)
from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
from Model.BoundaryCondition.BoundaryConditionList import BoundaryConditionList
class SetNameCommand(QUndoCommand):
def __init__(self, lst, index, new_value):
QUndoCommand.__init__(self)
self._lst = lst
self._index = index
self._old = self._lst[self._index].name
self._new = new_value
def undo(self):
self._lst[self._index].name = self._old
def redo(self):
self._lst[self._index].name = self._new
class SetNodeCommand(QUndoCommand):
def __init__(self, lst, index, node):
QUndoCommand.__init__(self)
self._lst = lst
self._index = index
self._old = self.lst[index].node
self._new = node
def undo(self):
self._lst[self._index].node = self._old
def redo(self):
self._lst[self._index].node = self._new
class SetTypeCommand(QUndoCommand):
def __init__(self, lst, index, _type):
QUndoCommand.__init__(self)
self._lst = lst
self._index = index
self._type = _type
self._old = self.lst[index]
self._new = self.lst[index].convert(self._type)
def undo(self):
self._lst[self._index] = self._old
def redo(self):
self._lst[self._index] = self._new
class AddCommand(QUndoCommand):
def __init__(self, lst, index):
QUndoCommand.__init__(self)
self._lst = lst
self._index = index
self._new = None
def undo(self):
self._lst.delete_i([self._index])
def redo(self):
if self._new is None:
self._new = self._lst.new(self._index)
else:
self._lst.insert(self._index, self._new)
class DelCommand(QUndoCommand):
def __init__(self, lst, rows):
QUndoCommand.__init__(self)
self._lst = lst
self._rows = rows
self._bc = []
for row in rows:
self._bc.append((row, self._lst[row]))
self._bc.sort()
def undo(self):
for row, el in self._bc:
self._lst.insert(row, el)
def redo(self):
self._lst.delete_i(self._rows)
class SortCommand(QUndoCommand):
def __init__(self, lst, _reverse):
QUndoCommand.__init__(self)
self._lst = lst
self._reverse = _reverse
self.old = self._lst.copy()
self._indexes = None
def undo(self):
ll = self._lst.copy()
self._lst.sort(
key=lambda x: self._indexes[ll.index(x)]
)
def redo(self):
self._lst.sort(self._reverse)
if self._indexes is None:
self._indexes = list(
map(
lambda p: self._old.index(p),
self._lst
)
)
self._old = None
class MoveCommand(QUndoCommand):
def __init__(self, lst, up, i):
QUndoCommand.__init__(self)
self._lst = lst
self._up = up == "up"
self._i = i
def undo(self):
if self._up:
self._lst.move_up(self._i)
else:
self._lst.move_down(self._i)
def redo(self):
if self._up:
self._lst.move_up(self._i)
else:
self._lst.move_down(self._i)
class PasteCommand(QUndoCommand):
def __init__(self, lst, row, bc):
QUndoCommand.__init__(self)
self._lst = lst
self._row = row
self._bc = deepcopy(bc)
self._bc.reverse()
def undo(self):
self._lst.delete(self._bc)
def redo(self):
for bc in self._bc:
self._lst.insert(self._row, bc)
class DuplicateCommand(QUndoCommand):
def __init__(self, lst, rows, bc):
QUndoCommand.__init__(self)
self._lst = lst
self._rows = rows
self._bc = deepcopy(bc)
self._bc.reverse()
def undo(self):
self._lst.delete(self._bc)
def redo(self):
for profile in self._profiles:
self._lst.insert(self._rows[0], profile)
# -*- coding: utf-8 -*-
from tools import trace, timer
from View.ASubWindow import ASubMainWindow
from View.ListedSubWindow import ListedSubWindow
from PyQt5.QtGui import (
QKeySequence,
)
from PyQt5.QtCore import (
Qt, QVariant, QAbstractTableModel,
QCoreApplication,
QCoreApplication, QModelIndex, pyqtSlot,
)
from PyQt5.QtWidgets import (
QDialogButtonBox, QPushButton, QLineEdit,
QFileDialog, QTableView, QAbstractItemView,
QUndoStack, QShortcut, QAction, QItemDelegate,
QComboBox,
)
from View.BoundaryCondition.BCUndoCommand import (
SetNameCommand, SetNodeCommand, SetTypeCommand,
AddCommand, DelCommand, SortCommand,
MoveCommand, PasteCommand, DuplicateCommand,
)
from Model.BoundaryCondition.BoundaryConditionTypes import (
NotDefined, PonctualContribution,
TimeOverZ, TimeOverDebit, ZOverDebit
)
from View.BoundaryCondition.EditBoundaryConditionWindow import EditBoundaryConditionWindow
_translate = QCoreApplication.translate
long_types = {
"ND": _translate("BoundaryCondition", "Not defined"),
"PC": _translate("BoundaryCondition", "Ponctual contribution"),
"TZ": _translate("BoundaryCondition", "Time over Z"),
"TD": _translate("BoundaryCondition", "Time over Debit"),
......@@ -30,11 +48,63 @@ table_headers = {
"node": _translate("BoundaryCondition", "Node")
}
BC_types = {
"ND": NotDefined,
"PC": PonctualContribution,
"TZ": TimeOverZ,
"TD": TimeOverDebit,
"ZD": ZOverDebit
}
class ComboBoxDelegate(QItemDelegate):
def __init__(self, data=None, mode="type", parent=None):
super(ComboBoxDelegate, self).__init__(parent)
self._data = data
self._mode = mode
def createEditor(self, parent, option, index):
self.editor = QComboBox(parent)
if self._mode == "type":
self.editor.addItems(BC_types.keys())
else:
self.editor.addItems(
["Not associate"] +
self._data.nodes_names()
)
self.editor.setCurrentText(index.data(Qt.DisplayRole))
return self.editor
def setEditorData(self, editor, index):
value = index.data(Qt.DisplayRole)
self.editor.currentTextChanged.connect(self.currentItemChanged)
def setModelData(self, editor, model, index):
text = str(editor.currentText())
model.setData(index, text)
editor.close()
editor.deleteLater()
def updateEditorGeometry(self, editor, option, index):
r = QRect(option.rect)
if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None:
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
editor.setGeometry(r)
@pyqtSlot()
def currentItemChanged(self):
self.commitData.emit(self.sender())
class TableModel(QAbstractTableModel):
def __init__(self, data=None):
def __init__(self, data=None, undo=None):
super(QAbstractTableModel, self).__init__()
self._headers = list(table_headers.keys())
self._data = data
self._undo = undo
self._lst = self._data.boundary_condition
def flags(self, index):
......@@ -57,12 +127,12 @@ class TableModel(QAbstractTableModel):
column = index.column()
if self._headers[column] == "name":
return self.lst[row].name
return self._lst[row].name
elif self._headers[column] == "type":
t = self.lst[row].bctype
t = self._lst[row].bctype
return long_types[t]
elif self._headers[column] == "node":
n = self.lst[row].node
n = self._lst[row].node
if n is None:
return "-"
return n.name
......@@ -83,15 +153,104 @@ class TableModel(QAbstractTableModel):
column = index.column()
if self._headers[column] == "name":
self.lst[row].name = value
self._undo.push(
SetNameCommand(
self._lst, row, value
)
)
elif self._headers[column] == "type":
self.lst[row].bctype = value
self._undo.push(
SetTypeCommand(
self._lst, row, BC_types[value]
)
)
elif self._headers[column] == "node":
self.lst[row].node = value
self._undo.push(
SetNodeCommand(
self._lst, row, self._data.node(value)
)
)
self.dataChanged.emit(index, index)
return True
def add(self, row, parent=QModelIndex()):
self.beginInsertRows(parent, row, row - 1)
self._undo.push(
AddCommand(
self._lst, row
)
)
self.endInsertRows()
self.layoutChanged.emit()
def delete(self, rows, parent=QModelIndex()):
self.beginRemoveRows(parent, rows[0], rows[-1])
self._undo.push(
DelCommand(
self._lst, rows
)
)
self.endRemoveRows()
def sort(self, _reverse, parent=QModelIndex()):
self.layoutAboutToBeChanged.emit()
self._undo_stack.push(
SortCommand(
self._lst, False
)
)
self.layoutAboutToBeChanged.emit()
self.layoutChanged.emit()
def move_up(self, row, parent=QModelIndex()):
if row <= 0:
return
target = row + 2
self.beginMoveRows(parent, row - 1, row - 1, parent, target)
self._undo_stack.push(
MoveCommand(
self._lst, "up", row
)
)
self.endMoveRows()
self.layoutChanged.emit()
def move_down(self, index, parent=QModelIndex()):
if row > len(self._lst):
return
target = row
self.beginMoveRows(parent, row + 1, row + 1, parent, target)
self._undo_stack.push(
MoveCommand(
self._lst, "down", row
)
)
self.endMoveRows()
self.layoutChanged.emit()
def undo(self):
self._undo.undo()
self.layoutChanged.emit()
def redo(self):
self._undo.redo()
self.layoutChanged.emit()
class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
def __init__(self, title="BoundaryConditions", study=None, parent=None):
......@@ -100,14 +259,109 @@ class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
)
self._study = study
self._lst = self._study.river.boundary_condition
self.setup_sc()
self.setup_table()
self.setup_connections()
self.ui.setWindowTitle(title)
def setup_sc(self):
self._undo_stack = QUndoStack()
self.undo_sc = QShortcut(QKeySequence.Undo, self)
self.redo_sc = QShortcut(QKeySequence.Redo, self)
self.copy_sc = QShortcut(QKeySequence.Copy, self)
self.paste_sc = QShortcut(QKeySequence.Paste, self)
def setup_table(self):
table = self.find(QTableView, "tableView")
self._table = TableModel(
data = self._study.river
data = self._study.river,
undo = self._undo_stack
)
table.setModel(self._table)
self.ui.setWindowTitle(title)
self._delegate_type = ComboBoxDelegate(
data = self._study.river,
mode = "type"
)
self._delegate_node = ComboBoxDelegate(
data = self._study.river,
mode = "node"
)
table.setItemDelegateForColumn(
1, self._delegate_type
)
table.setItemDelegateForColumn(
2, self._delegate_node
)
def setup_connections(self):
self.find(QAction, "action_add").triggered.connect(self.add)
self.find(QAction, "action_del").triggered.connect(self.delete)
self.find(QAction, "action_edit").triggered.connect(self.edit)
self.find(QAction, "action_sort").triggered.connect(self.sort)
self.undo_sc.activated.connect(self.undo)
self.redo_sc.activated.connect(self.redo)
self.copy_sc.activated.connect(self.copy)
self.paste_sc.activated.connect(self.paste)
def index_selected_row(self):
table = self.find(QTableView, "tableView")
return table.selectionModel()\
.selectedRows()[0]\
.row()
def index_selected_rows(self):
table = self.find(QTableView, "tableView")
return list(
set(
map(
lambda i: i.row(),
table.selectedIndexes()
)
)
)
def add(self):
if len(self._lst) == 0:
self._table.add(0)
else:
row = self.index_selected_row()
self._table.add(row)
def delete(self):
rows = self.index_selected_rows()
self._table.delete(rows)
def sort(self):
self._table.sort(False)
def move_up(self):
row = self.index_selected_row()
self._table.move_up(row)
def move_down(self):
row = self.index_selected_row()
self._table.move_down(row)
def copy(self):
print("TODO")
def paste(self):
print("TODO")
def undo(self):
self._table.undo()
def redo(self):
self._table.redo()
def edit(self):
win = EditBoundaryConditionWindow(data=None, parent=self)
......
......@@ -90,7 +90,7 @@ def trace(func):
value = func(*args, **kwargs)
t = time.ctime()
r = f"{head}[{t}] Return {func.__module__}.{Fore.GREEN}{func.__qualname__}{Style.RESET_ALL}"
r = f"{head}[{t}] Return {func.__module__}.{Fore.GREEN}{func.__qualname__}{Style.RESET_ALL}: {value}"
print(r)
return value
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment