From ff9c47eb838b2a2faa8d0a1acce48c164c90126a Mon Sep 17 00:00:00 2001
From: Pierre-Antoine Rouby <pierre-antoine.rouby@inrae.fr>
Date: Wed, 26 Apr 2023 11:51:48 +0200
Subject: [PATCH] geometry: Profile: Fix delete command undo point order.

---
 src/Model/Geometry/Profile.py                 | 42 +++++++++++++++----
 .../Geometry/Profile/ProfileUndoCommand.py    | 11 ++---
 .../Geometry/Profile/qtableview_profile.py    |  2 +-
 src/tools.py                                  |  2 +
 4 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/src/Model/Geometry/Profile.py b/src/Model/Geometry/Profile.py
index 2a4e690b..ae0eef4b 100644
--- a/src/Model/Geometry/Profile.py
+++ b/src/Model/Geometry/Profile.py
@@ -140,19 +140,47 @@ class Profile(object):
         self._points.insert(index, point)
 
 
-    def delete(self, index: int):
-        """Delete the point at index
+    def delete(self, indexes: int):
+        """Delete points at index
 
         Args:
-            index: Index of point.
+            indexes: List of index of points.
 
         Returns:
             Nothing.
         """
-        try:
-            self._points.pop(index)
-        except IndexError:
-            raise IndexError(f"Invalid point index: {index}")
+        points = set(
+            map(
+                lambda e: e[1],
+                filter(
+                    lambda e: e[0] in indexes,
+                    enumerate(self.points)
+                )
+            )
+        )
+
+        self._points = list(
+            filter(
+                lambda p: p not in points,
+                self.points
+            )
+        )
+
+    def delete_points(self, points):
+        """Delete some elements in profile list
+
+        Args:
+            points: The list of profile to delete
+
+        Returns:
+            Nothing.
+        """
+        self._points = list(
+            filter(
+                lambda p: p not in points,
+                self.points
+            )
+        )
 
     # Move
 
diff --git a/src/View/Geometry/Profile/ProfileUndoCommand.py b/src/View/Geometry/Profile/ProfileUndoCommand.py
index 53945106..0797c6a5 100644
--- a/src/View/Geometry/Profile/ProfileUndoCommand.py
+++ b/src/View/Geometry/Profile/ProfileUndoCommand.py
@@ -69,18 +69,15 @@ class DelCommand(QUndoCommand):
 
         self._points = []
         for row in rows:
-            self._points.append(self._profile.point(row))
-        self._points.reverse()
+            self._points.append((row, self._profile.point(row)))
+        self._points.sort()     # Sort by row index
 
     def undo(self):
-        row = self._rows[0]
-        for point in self._points:
+        for row, 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)
+        self._profile.delete(self._rows)
 
 class SortCommand(QUndoCommand):
     def __init__(self, profile, column, _reverse):
diff --git a/src/View/Geometry/Profile/qtableview_profile.py b/src/View/Geometry/Profile/qtableview_profile.py
index d103e35b..7ba364e9 100644
--- a/src/View/Geometry/Profile/qtableview_profile.py
+++ b/src/View/Geometry/Profile/qtableview_profile.py
@@ -201,7 +201,7 @@ class TableEditableModel(QAbstractTableModel):
         self.layoutChanged.emit()
 
     def remove_rows(self, rows, parent=QModelIndex()):
-        self.beginRemoveRows(parent, rows[0], row[-1])
+        self.beginRemoveRows(parent, rows[0], rows[-1])
 
         self._undo_stack.push(
             DelCommand(
diff --git a/src/tools.py b/src/tools.py
index c26e9fe9..6ae8996b 100644
--- a/src/tools.py
+++ b/src/tools.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 
 import time
+import traceback
 
 from colorama import Fore
 from colorama import Back
@@ -59,6 +60,7 @@ def timer(func):
             print(f"[{Fore.RED}ERROR{Style.RESET_ALL}]" +
                   f"[{func.__module__}.{Fore.GREEN}{func.__qualname__}{Style.RESET_ALL}]: " +
                   f"{Fore.RED}{e}{Style.RESET_ALL}")
+            traceback.print_exc()
 
         end_time = time.perf_counter()
         run_time = end_time - start_time
-- 
GitLab