@@ -185,6 +185,7 @@ def __init__(
185
185
total_width += self .columnWidth (k )
186
186
self .viewport ().resize (min (total_width , 1024 ), self .height ())
187
187
QShortcut (QKeySequence (QKeySequence .Copy ), self , self .copy )
188
+ QShortcut (QKeySequence (QKeySequence .Paste ), self , self .paste )
188
189
self .horizontalScrollBar ().valueChanged .connect (
189
190
lambda val : self .load_more_data (val , columns = True )
190
191
)
@@ -409,6 +410,15 @@ def setup_cell_menu(self) -> QMenu:
409
410
triggered = self .copy ,
410
411
context = Qt .ShortcutContext .WidgetShortcut ,
411
412
)
413
+ self .paste_action = create_action (
414
+ self ,
415
+ _ ("Paste" ),
416
+ shortcut = keybinding ("Paste" ),
417
+ icon = get_icon ("editpaste.png" ),
418
+ triggered = self .paste ,
419
+ context = Qt .ShortcutContext .WidgetShortcut ,
420
+ )
421
+ self .paste_action .setDisabled (self .model ().readonly )
412
422
about_action = create_action (
413
423
self ,
414
424
_ ("About..." ),
@@ -442,6 +452,7 @@ def setup_cell_menu(self) -> QMenu:
442
452
)
443
453
actions = (
444
454
self .copy_action ,
455
+ self .paste_action ,
445
456
None ,
446
457
insert_row_action ,
447
458
insert_col_action ,
@@ -454,6 +465,7 @@ def setup_cell_menu(self) -> QMenu:
454
465
else :
455
466
actions = (
456
467
self .copy_action ,
468
+ self .paste_action ,
457
469
None ,
458
470
about_action ,
459
471
)
@@ -587,6 +599,47 @@ def copy(self) -> None:
587
599
clipboard = QApplication .clipboard ()
588
600
clipboard .setText (cliptxt )
589
601
602
+ @Slot ()
603
+ def paste (self ) -> None :
604
+ """Paste text from clipboard"""
605
+ cliptxt = QApplication .clipboard ().text ()
606
+ if not cliptxt :
607
+ return
608
+ try :
609
+ data = np .genfromtxt (io .StringIO (cliptxt ), delimiter = "\t " )
610
+ except ValueError :
611
+ data = np .array ([])
612
+ if data .size == 0 :
613
+ QMessageBox .warning (
614
+ self ,
615
+ _ ("Warning" ),
616
+ _ ("It was not possible to paste values for this array" ),
617
+ )
618
+ return
619
+
620
+ model = self .model ()
621
+
622
+ # Determine where to paste
623
+ start_row = self .currentIndex ().row ()
624
+ start_col = self .currentIndex ().column ()
625
+
626
+ # Iterate and paste each value
627
+ data = np .array (data , dtype = model .get_array ().dtype )
628
+ if data .ndim in (0 , 1 ):
629
+ data = data .reshape ((- 1 , 1 ))
630
+ for i in range (data .shape [0 ]):
631
+ for j in range (data .shape [1 ]):
632
+ if (start_row + i < model .total_rows ) and (
633
+ start_col + j < model .total_cols
634
+ ):
635
+ idx = model .index (start_row + i , start_col + j )
636
+ model .setData (idx , str (data [i , j ]))
637
+
638
+ model .dataChanged .emit (
639
+ model .index (start_row , start_col ),
640
+ model .index (start_row + data .shape [0 ] - 1 , start_col + data .shape [1 ] - 1 ),
641
+ )
642
+
590
643
591
644
class BaseArrayEditorWidget (QWidget ):
592
645
"""Base ArrayEditdorWidget class. Used to wrap handle n-dimensional normal Numpy's
0 commit comments