ソースを参照

feature: copy and paste polygons (#818)

* feature: copy and paste polygons

* copy -> duplicate

* copyClipboard -> copy

Co-authored-by: Kentaro Wada <www.kentaro.wada@gmail.com>
Sebastian Ruiz 3 年 前
コミット
7e7ed18738
3 ファイル変更41 行追加6 行削除
  1. 38 5
      labelme/app.py
  2. 2 0
      labelme/config/default_config.yaml
  3. 1 1
      labelme/widgets/canvas.py

+ 38 - 5
labelme/app.py

@@ -97,6 +97,8 @@ class MainWindow(QtWidgets.QMainWindow):
 
         self._noSelectionSlot = False
 
+        self._copied_shapes = None
+
         # Main widgets and related state.
         self.labelDialog = LabelDialog(
             parent=self,
@@ -383,14 +385,30 @@ class MainWindow(QtWidgets.QMainWindow):
             self.tr("Delete the selected polygons"),
             enabled=False,
         )
-        copy = action(
+        duplicate = action(
             self.tr("Duplicate Polygons"),
-            self.copySelectedShape,
+            self.duplicateSelectedShape,
             shortcuts["duplicate_polygon"],
             "copy",
             self.tr("Create a duplicate of the selected polygons"),
             enabled=False,
         )
+        copy = action(
+            self.tr("Copy Polygons"),
+            self.copySelectedShape,
+            shortcuts["copy_polygon"],
+            "copy_clipboard",
+            self.tr("Copy selected polygons to clipboard"),
+            enabled=False,
+        )
+        paste = action(
+            self.tr("Paste Polygons"),
+            self.pasteSelectedShape,
+            shortcuts["paste_polygon"],
+            "paste",
+            self.tr("Paste copied polygons"),
+            enabled=False,
+        )
         undoLastPoint = action(
             self.tr("Undo last point"),
             self.canvas.undoLastPoint,
@@ -571,7 +589,9 @@ class MainWindow(QtWidgets.QMainWindow):
             toggleKeepPrevMode=toggle_keep_prev_mode,
             delete=delete,
             edit=edit,
+            duplicate=duplicate,
             copy=copy,
+            paste=paste,
             undoLastPoint=undoLastPoint,
             undo=undo,
             removePoint=removePoint,
@@ -598,7 +618,7 @@ class MainWindow(QtWidgets.QMainWindow):
             # XXX: need to add some actions here to activate the shortcut
             editMenu=(
                 edit,
-                copy,
+                duplicate,
                 delete,
                 None,
                 undo,
@@ -618,7 +638,9 @@ class MainWindow(QtWidgets.QMainWindow):
                 createLineStripMode,
                 editMode,
                 edit,
+                duplicate,
                 copy,
+                paste,
                 delete,
                 undo,
                 undoLastPoint,
@@ -718,7 +740,9 @@ class MainWindow(QtWidgets.QMainWindow):
             None,
             createMode,
             editMode,
+            duplicate,
             copy,
+            paste,
             delete,
             undo,
             brightnessContrast,
@@ -1097,6 +1121,7 @@ class MainWindow(QtWidgets.QMainWindow):
         self._noSelectionSlot = False
         n_selected = len(selected_shapes)
         self.actions.delete.setEnabled(n_selected)
+        self.actions.duplicate.setEnabled(n_selected)
         self.actions.copy.setEnabled(n_selected)
         self.actions.edit.setEnabled(n_selected == 1)
 
@@ -1259,13 +1284,21 @@ class MainWindow(QtWidgets.QMainWindow):
             )
             return False
 
-    def copySelectedShape(self):
-        added_shapes = self.canvas.copySelectedShapes()
+    def duplicateSelectedShape(self):
+        added_shapes = self.canvas.duplicateSelectedShapes()
         self.labelList.clearSelection()
         for shape in added_shapes:
             self.addLabel(shape)
         self.setDirty()
 
+    def pasteSelectedShape(self):
+        self.loadShapes(self._copied_shapes, replace=False)
+        self.setDirty()
+
+    def copySelectedShape(self):
+        self._copied_shapes = [s.copy() for s in self.canvas.selectedShapes]
+        self.actions.paste.setEnabled(len(self._copied_shapes) > 0)
+
     def labelSelectionChanged(self):
         if self._noSelectionSlot:
             return

+ 2 - 0
labelme/config/default_config.yaml

@@ -96,6 +96,8 @@ shortcuts:
   edit_polygon: Ctrl+J
   delete_polygon: Delete
   duplicate_polygon: Ctrl+D
+  copy_polygon: Ctrl+C
+  paste_polygon: Ctrl+V
   undo: Ctrl+Z
   undo_last_point: Ctrl+Z
   add_point_to_edge: Ctrl+Shift+P

+ 1 - 1
labelme/widgets/canvas.py

@@ -553,7 +553,7 @@ class Canvas(QtWidgets.QWidget):
         self.storeShapes()
         self.update()
 
-    def copySelectedShapes(self):
+    def duplicateSelectedShapes(self):
         if self.selectedShapes:
             self.selectedShapesCopy = [s.copy() for s in self.selectedShapes]
             self.boundedShiftShapes(self.selectedShapesCopy)