From 25b8ff6adf0d2a030e2672b9547d2be61145073f Mon Sep 17 00:00:00 2001
From: Pierre-Antoine Rouby <pierre-antoine.rouby@inrae.fr>
Date: Thu, 27 Apr 2023 09:50:09 +0200
Subject: [PATCH] geometry: Prepare duplicate command.

---
 src/Model/Geometry/Reach.py           |  3 ---
 src/View/Geometry/GeometryWindow.py   | 18 ++++++++++++++++++
 src/View/Geometry/ReachUndoCommand.py | 25 ++++++++++++++++++++++---
 src/View/Geometry/qtableview_reach.py | 14 ++++++++++++++
 4 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py
index 7c8ebcd5..0fff437c 100644
--- a/src/Model/Geometry/Reach.py
+++ b/src/Model/Geometry/Reach.py
@@ -23,9 +23,6 @@ class Reach:
         self._guidelines_is_valid = False
         self._guidelines = {}
 
-        # Copy/Paste
-        self.__list_copied_profiles = []
-
     def profile(self, i):
         """Returns profile at index i
 
diff --git a/src/View/Geometry/GeometryWindow.py b/src/View/Geometry/GeometryWindow.py
index 7fc7f851..e6ec58f9 100644
--- a/src/View/Geometry/GeometryWindow.py
+++ b/src/View/Geometry/GeometryWindow.py
@@ -367,6 +367,24 @@ class GeometryWindow(QMainWindow, WindowToolKit):
         self._tablemodel.move_row_down(row)
         self.select_current_profile()
 
+    def duplicate(self):
+        rows = [
+            row.row() for row in
+            self.tableView.selectionModel().selectedRows()
+        ]
+
+        profiles = []
+        for row in rows:
+            profiles.append(
+                self._reach.profile(row)
+            )
+
+        if len(profiles) == 0:
+            return
+
+        self._tablemodel.duplicate(rows, profiles)
+        self.select_current_profile()
+
     def copy(self):
         rows = self.tableView\
                    .selectionModel()\
diff --git a/src/View/Geometry/ReachUndoCommand.py b/src/View/Geometry/ReachUndoCommand.py
index 7fa63010..ed911c66 100644
--- a/src/View/Geometry/ReachUndoCommand.py
+++ b/src/View/Geometry/ReachUndoCommand.py
@@ -128,14 +128,33 @@ class PasteCommand(QUndoCommand):
                 profiles
             )
         )
+        self._profiles.reverse()
 
     def undo(self):
         self._reach.delete_profiles(self._profiles)
 
     def redo(self):
-        self._profiles.reverse()
+        for profile in self._profiles:
+            self._reach.insert_profile(self._row, profile)
 
-        for pro in self._profiles:
-            self._reach.insert_profile(self._row, pro)
 
+class DuplicateCommand(QUndoCommand):
+    def __init__(self, reach, rows, profiles):
+        QUndoCommand.__init__(self)
+
+        self._reach = reach
+        self._rows = rows
+        self._profiles = list(
+            map(
+                lambda p: deepcopy(p),
+                profiles
+            )
+        )
         self._profiles.reverse()
+
+    def undo(self):
+        self._reach.delete_profiles(self._profiles)
+
+    def redo(self):
+        for profile in self._profiles:
+            self._reach.insert_profile(self._rows[0], profile)
diff --git a/src/View/Geometry/qtableview_reach.py b/src/View/Geometry/qtableview_reach.py
index db4aba72..43d96cda 100644
--- a/src/View/Geometry/qtableview_reach.py
+++ b/src/View/Geometry/qtableview_reach.py
@@ -212,6 +212,20 @@ class TableEditableModel(QAbstractTableModel):
         self.endMoveRows()
         self.layoutChanged.emit()
 
+    def duplicate(self, rows, profiles):
+        self.layoutAboutToBeChanged.emit()
+
+        self._undo_stack.push(
+            DuplicateCommand(
+                self._reach, rows,
+                profiles
+            )
+        )
+
+        self.layoutAboutToBeChanged.emit()
+        self.layoutChanged.emit()
+
+
     def paste(self, row, header, data):
         if row > self._reach.number_profiles:
             return
-- 
GitLab