|
1 | 1 | import os
|
2 | 2 | from collections import defaultdict
|
| 3 | +from copy import deepcopy |
3 | 4 | from datetime import datetime
|
4 | 5 | from functools import partial
|
5 | 6 | from math import ceil, log10
|
|
13 | 14 | from napari.layers import Image, Points, Shapes, Tracks
|
14 | 15 | from napari.layers.points._points_key_bindings import register_points_action
|
15 | 16 | from napari.layers.utils import color_manager
|
| 17 | +from napari.layers.utils.layer_utils import _features_to_properties |
16 | 18 | from napari.utils.events import Event
|
17 | 19 | from napari.utils.history import get_save_history, update_save_history
|
18 | 20 | from qtpy.QtCore import Qt, QTimer, Signal, QSize
|
@@ -78,6 +80,75 @@ def guess_continuous(property):
|
78 | 80 | color_manager.guess_continuous = guess_continuous
|
79 | 81 |
|
80 | 82 |
|
| 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 | + |
81 | 152 | # Hack to save a KeyPoints layer without showing the Save dialog
|
82 | 153 | def _save_layers_dialog(self, selected=False):
|
83 | 154 | """Save layers (all or selected) to disk, using ``LayerList.save()``.
|
@@ -477,6 +548,8 @@ def on_insert(self, event):
|
477 | 548 | layer.metadata["controls"] = self
|
478 | 549 | layer.text.visible = False
|
479 | 550 | layer.bind_key("M", self.cycle_through_label_modes)
|
| 551 | + func = partial(_paste_data, store=store) |
| 552 | + layer._paste_data = MethodType(func, layer) |
480 | 553 | layer.add = MethodType(keypoints._add, store)
|
481 | 554 | layer.events.add(query_next_frame=Event)
|
482 | 555 | layer.events.query_next_frame.connect(store._advance_step)
|
|
0 commit comments