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

geometry: Profile: Update qtable and add undo commands.

Showing with 401 additions and 323 deletions
+401 -323
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Model.Geometry.Point import Point
from Model.Except import NotImplementedMethodeError from Model.Except import NotImplementedMethodeError
class Profile(object): class Profile(object):
...@@ -20,6 +21,14 @@ class Profile(object): ...@@ -20,6 +21,14 @@ class Profile(object):
self._profile_type = _type self._profile_type = _type
@property
def number_points(self):
return len(self._points)
@property
def points(self):
return self._points.copy()
@property @property
def reach(self): def reach(self):
return self._reach return self._reach
...@@ -100,6 +109,11 @@ class Profile(object): ...@@ -100,6 +109,11 @@ class Profile(object):
def profile_type(self, value: str): def profile_type(self, value: str):
self._profile_type = value self._profile_type = value
def point(self, i:int):
if i < len(self._points):
return self._points[i]
return None
def named_points(self): def named_points(self):
"""List of named point """List of named point
...@@ -110,6 +124,81 @@ class Profile(object): ...@@ -110,6 +124,81 @@ class Profile(object):
return [point for point in self._points return [point for point in self._points
if point.point_is_named()] if point.point_is_named()]
def insert_point(self, index: int, point:Point):
"""Insert point at index.
Args:
index: The index of new profile.
point: The point.
Returns:
Nothing.
"""
self._points.insert(index, point)
def delete(self, index: int):
"""Delete the point at index
Args:
index: Index of point.
Returns:
Nothing.
"""
try:
self._points.pop(index)
except IndexError:
raise IndexError(f"Invalid point index: {index}")
# Move
def move_up_point(self, index: int):
if index < len(self._points):
next = index - 1
p = self._points
p[index], p[next] = p[next], p[index]
def move_down_point(self, index: int):
if index >= 0:
prev = index + 1
p = self._points
p[index], p[prev] = p[prev], p[index]
# Sort
@timer
def sort(self, column, is_reversed: bool = False):
predicate = lambda p: p.x
if column == 'y':
predicate = lambda p: p.y
elif column == 'z':
predicate = lambda p: p.z
self._profiles = sorted(
self._points,
key=predicate,
reverse=is_reversed
)
@timer
def sort_with_indexes(self, indexes: list):
if len(self._points) != len(indexes):
print("TODO: CRITICAL ERROR!")
self._points = list(
map(
lambda x: x[1],
sorted(
enumerate(self.points),
key=lambda x: indexes[x[0]]
)
)
)
# Abstract method, must be implemented for in non abstract class # Abstract method, must be implemented for in non abstract class
def get_station(self): def get_station(self):
raise NotImplementedMethodeError(self, self.get_station) raise NotImplementedMethodeError(self, self.get_station)
...@@ -117,22 +117,8 @@ class ProfileXYZ(Profile): ...@@ -117,22 +117,8 @@ class ProfileXYZ(Profile):
point_xyz = PointXYZ(0., 0., 0.) point_xyz = PointXYZ(0., 0., 0.)
self._points.append(point_xyz) self._points.append(point_xyz)
def delete(self, index: int):
"""Delete the point at index
Args:
index: Index of point.
Returns:
Nothing.
"""
try:
self._points.pop(index)
except IndexError:
raise IndexError(f"Invalid point index: {index}")
def insert(self, index: int): def insert(self, index: int):
"""Insert a new profile at index. """Insert a new point at index.
Args: Args:
index: The index of new profile. index: The index of new profile.
...@@ -140,35 +126,8 @@ class ProfileXYZ(Profile): ...@@ -140,35 +126,8 @@ class ProfileXYZ(Profile):
Returns: Returns:
Nothing. Nothing.
""" """
profile = ProfileXYZ() point = PointXYZ(0., 0., 0.)
self._points.insert(index, profile) self._points.insert(index, point)
def delete1(self, list_index: list):
"""Delete a list of points
Args:
list_index: Indexes list.
Returns:
Nothing.
"""
try:
if list_index:
indices = sorted(list(set(list_index)), reverse=True)
for idx in indices:
# if idx < len(self._list_profiles) :
try:
self._points.pop(idx)
except IndexError:
print("Empty list, nothing to delete")
except TypeError:
if isinstance(list_index, int):
self._points.pop(list_index)
print(f"\n{list_index} is not a list\n")
else:
raise TypeError(
f"{list_index} is instance of unexpected type '{type(list_index)}'"
)
def filter_isnan(self, lst): def filter_isnan(self, lst):
"""Returns the input list without 'nan' element """Returns the input list without 'nan' element
......
# -*- coding: utf-8 -*-
from tools import trace, timer
from PyQt5.QtWidgets import (
QMessageBox, QUndoCommand, QUndoStack,
)
from Model.Geometry.Profile import Profile
class SetDataCommand(QUndoCommand):
def __init__(self, profile, index, old_value, new_value):
QUndoCommand.__init__(self)
self._profile = profile
self._index = index
self._old = old_value
self._new = new_value
class SetXCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).x = self._old
def redo(self):
self._profile.point(self._index).x = self._new
class SetYCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).y = self._old
def redo(self):
self._profile.point(self._index).y = self._new
class SetZCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).z = self._old
def redo(self):
self._profile.point(self._index).z = self._new
class SetNameCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).name = self._old
def redo(self):
self._profile.point(self._index).name = self._new
class AddCommand(QUndoCommand):
def __init__(self, profile, index):
QUndoCommand.__init__(self)
self._profile = profile
self._index = index
def undo(self):
self._profile.delete(self._index)
def redo(self):
self._profile.insert(self._index)
class DelCommand(QUndoCommand):
def __init__(self, profile, rows):
QUndoCommand.__init__(self)
self._profile = profile
self._rows = rows
self._points = []
for row in rows:
self._points.append(self._profile.point(row))
self._points.reverse()
def undo(self):
row = self._rows[0]
for point in self._points:
self._profile.insert_point(row, point)
def redo(self):
row = self._rows[0]
for _ in self._rows:
self._profile.delete(row)
class SortCommand(QUndoCommand):
def __init__(self, profile, column _reverse):
QUndoCommand.__init__(self)
self._profile = profile
self._column = column
self._reverse = _reverse
old = self._profile.points
self._profile.sort(self.column, self._reverse)
new = self._profile.points
self._indexes = list(
map(
lambda p: old.index(p),
new
)
)
def undo(self):
self._profile.sort_with_indexes(self._indexes)
def redo(self):
self._profile.sort(self.column, self._reverse)
class MoveCommand(QUndoCommand):
def __init__(self, profile, up, i):
QUndoCommand.__init__(self)
self._profile = profile
self._up = up == "up"
self._i = i
def undo(self):
if self._up:
self._profile.move_up_point(self._i)
else:
self._profile.move_down_point(self._i)
def redo(self):
if self._up:
self._profile.move_up_point(self._i)
else:
self._profile.move_down_point(self._i)
class PasteCommand(QUndoCommand):
def __init__(self, profile, row, points):
QUndoCommand.__init__(self)
self._profile = profile
self._row = row
self._points = points
self._points.reverse()
def undo(self):
for ind in range(len(self._profiles)):
self._profile.delete(self._row)
def redo(self):
for point in self._points:
self._profile.insert_point(self._row, point)
# -*- coding: utf-8 -*-
import copy import copy
import sys import sys
import csv import csv
...@@ -93,7 +95,7 @@ class ProfileWindow(QMainWindow): ...@@ -93,7 +95,7 @@ class ProfileWindow(QMainWindow):
def graph(self): def graph(self):
""" """
Returns: Le tracé de la cote z en fonction de l'abscisse (calculée). Returns: Le tracé de la cote z en fonction de l'abscisse (calculée).
""" """
x = self._model.station # abscisse en travers x = self._model.station # abscisse en travers
y = self._model.z # cote z y = self._model.z # cote z
......
This diff is collapsed.
...@@ -178,11 +178,11 @@ class PandasModelEditable(QAbstractTableModel): ...@@ -178,11 +178,11 @@ class PandasModelEditable(QAbstractTableModel):
def move_row_up(self, row, parent=QModelIndex()): def move_row_up(self, row, parent=QModelIndex()):
target = row + 2
if row <= 0: if row <= 0:
return return
target = row + 2
self.beginMoveRows(parent, row - 1, row - 1, parent, target) self.beginMoveRows(parent, row - 1, row - 1, parent, target)
self._undo_stack.push( self._undo_stack.push(
...@@ -195,11 +195,11 @@ class PandasModelEditable(QAbstractTableModel): ...@@ -195,11 +195,11 @@ class PandasModelEditable(QAbstractTableModel):
self.layoutChanged.emit() self.layoutChanged.emit()
def move_row_down(self, row, parent=QModelIndex()): def move_row_down(self, row, parent=QModelIndex()):
target = row
if row > self._reach.number_profiles: if row > self._reach.number_profiles:
return return
target = row
self.beginMoveRows(parent, row + 1, row + 1, parent, target) self.beginMoveRows(parent, row + 1, row + 1, parent, target)
self._undo_stack.push( self._undo_stack.push(
...@@ -249,8 +249,8 @@ class Delegate(QtWidgets.QStyledItemDelegate): ...@@ -249,8 +249,8 @@ class Delegate(QtWidgets.QStyledItemDelegate):
return QtWidgets.QLineEdit(parent) return QtWidgets.QLineEdit(parent)
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
value = index.model().data(index, Qt.DisplayRole) # DisplayRole value = index.model().data(index, Qt.DisplayRole)
editor.setText(str(value)) # récupère la valeur de la cellule applique la méthode définie dans setData editor.setText(str(value))
def setModelData(self, editor, model, index): def setModelData(self, editor, model, index):
model.setData(index, editor.text()) model.setData(index, editor.text())
......
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