Skip to content

Commit 88ac46d

Browse files
committed
Add copy/paste functionality
1 parent 75036c5 commit 88ac46d

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

src/napari_deeplabcut/_widgets.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
from collections import defaultdict
3+
from copy import deepcopy
34
from datetime import datetime
45
from functools import partial
56
from math import ceil, log10
@@ -13,6 +14,7 @@
1314
from napari.layers import Image, Points, Shapes, Tracks
1415
from napari.layers.points._points_key_bindings import register_points_action
1516
from napari.layers.utils import color_manager
17+
from napari.layers.utils.layer_utils import _features_to_properties
1618
from napari.utils.events import Event
1719
from napari.utils.history import get_save_history, update_save_history
1820
from qtpy.QtCore import Qt, QTimer, Signal, QSize
@@ -78,6 +80,75 @@ def guess_continuous(property):
7880
color_manager.guess_continuous = guess_continuous
7981

8082

83+
def _paste_data(self, store):
84+
"""Paste only currently unannotated data."""
85+
features = self._clipboard.pop("features")
86+
if features is None:
87+
return
88+
unannotated = [
89+
keypoints.Keypoint(label, id_) not in store.annotated_keypoints
90+
for label, id_ in zip(features["label"], features["id"])
91+
]
92+
new_features = features.iloc[unannotated]
93+
indices_ = self._clipboard.pop("indices")
94+
text_ = self._clipboard.pop("text")
95+
self._clipboard = {k: v[unannotated] for k, v in self._clipboard.items()}
96+
self._clipboard["features"] = new_features
97+
self._clipboard["indices"] = indices_
98+
if text_ is not None:
99+
new_text = {k: v[unannotated] for k, v in text_.items()}
100+
self._clipboard["text"] = new_text
101+
102+
npoints = len(self._view_data)
103+
totpoints = len(self.data)
104+
105+
if len(self._clipboard.keys()) > 0:
106+
not_disp = self._dims_not_displayed
107+
data = deepcopy(self._clipboard['data'])
108+
offset = [
109+
self._slice_indices[i] - self._clipboard['indices'][i]
110+
for i in not_disp
111+
]
112+
data[:, not_disp] = data[:, not_disp] + np.array(offset)
113+
self._data = np.append(self.data, data, axis=0)
114+
self._shown = np.append(
115+
self.shown, deepcopy(self._clipboard['shown']), axis=0
116+
)
117+
self._size = np.append(
118+
self.size, deepcopy(self._clipboard['size']), axis=0
119+
)
120+
121+
self._feature_table.append(self._clipboard['features'])
122+
123+
self.text._paste(**self._clipboard['text'])
124+
125+
self._edge_width = np.append(
126+
self.edge_width,
127+
deepcopy(self._clipboard['edge_width']),
128+
axis=0,
129+
)
130+
self._edge._paste(
131+
colors=self._clipboard['edge_color'],
132+
properties=_features_to_properties(
133+
self._clipboard['features']
134+
),
135+
)
136+
self._face._paste(
137+
colors=self._clipboard['face_color'],
138+
properties=_features_to_properties(
139+
self._clipboard['features']
140+
),
141+
)
142+
143+
self._selected_view = list(
144+
range(npoints, npoints + len(self._clipboard['data']))
145+
)
146+
self._selected_data = set(
147+
range(totpoints, totpoints + len(self._clipboard['data']))
148+
)
149+
self.refresh()
150+
151+
81152
# Hack to save a KeyPoints layer without showing the Save dialog
82153
def _save_layers_dialog(self, selected=False):
83154
"""Save layers (all or selected) to disk, using ``LayerList.save()``.
@@ -477,6 +548,8 @@ def on_insert(self, event):
477548
layer.metadata["controls"] = self
478549
layer.text.visible = False
479550
layer.bind_key("M", self.cycle_through_label_modes)
551+
func = partial(_paste_data, store=store)
552+
layer._paste_data = MethodType(func, layer)
480553
layer.add = MethodType(keypoints._add, store)
481554
layer.events.add(query_next_frame=Event)
482555
layer.events.query_next_frame.connect(store._advance_step)

0 commit comments

Comments
 (0)