tksheet 7.4.6__py3-none-any.whl → 7.4.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tksheet/sheet.py CHANGED
@@ -5,14 +5,20 @@ from bisect import bisect_left
5
5
  from collections import deque
6
6
  from collections.abc import Callable, Generator, Hashable, Iterator, Sequence
7
7
  from contextlib import suppress
8
+ from functools import partial
8
9
  from itertools import accumulate, chain, filterfalse, islice, product, repeat
9
10
  from operator import attrgetter
11
+ from re import IGNORECASE, escape, sub
10
12
  from timeit import default_timer
11
13
  from tkinter import ttk
12
14
  from typing import Any, Literal
13
15
 
14
16
  from .column_headers import ColumnHeaders
15
17
  from .constants import (
18
+ ALL_BINDINGS,
19
+ BINDING_TO_ATTR,
20
+ MODIFIED_BINDINGS,
21
+ SELECT_BINDINGS,
16
22
  USER_OS,
17
23
  align_value_error,
18
24
  backwards_compatibility_keys,
@@ -21,11 +27,13 @@ from .constants import (
21
27
  rc_binding,
22
28
  scrollbar_options_keys,
23
29
  )
30
+ from .find_window import replacer
24
31
  from .functions import (
25
32
  add_highlight,
26
33
  add_to_options,
27
34
  alpha2idx,
28
35
  bisect_in,
36
+ box_gen_coords,
29
37
  consecutive_ranges,
30
38
  convert_align,
31
39
  del_from_options,
@@ -42,6 +50,7 @@ from .functions import (
42
50
  idx_param_to_int,
43
51
  is_iterable,
44
52
  key_to_span,
53
+ mod_event_val,
45
54
  new_tk_event,
46
55
  num2alpha,
47
56
  pop_positions,
@@ -51,6 +60,7 @@ from .functions import (
51
60
  span_ranges,
52
61
  stored_event_dict,
53
62
  tksheet_type_error,
63
+ try_binding,
54
64
  unpack,
55
65
  )
56
66
  from .main_table import MainTable
@@ -293,6 +303,7 @@ class Sheet(tk.Frame):
293
303
  row_height: str | int | None = None,
294
304
  row_index_width: int | None = None,
295
305
  expand_sheet_if_paste_too_big: bool | None = None,
306
+ **kwargs,
296
307
  ) -> None:
297
308
  super().__init__(
298
309
  parent,
@@ -604,97 +615,10 @@ class Sheet(tk.Frame):
604
615
  # Bindings and Functionality
605
616
 
606
617
  def enable_bindings(self, *bindings: Binding) -> Sheet:
607
- """
608
- List of available bindings:
609
- - "all"
610
- - "single_select"
611
- - "toggle_select"
612
- - "drag_select"
613
- - "select_all"
614
- - "column_drag_and_drop" / "move_columns"
615
- - "row_drag_and_drop" / "move_rows"
616
- - "column_select"
617
- - "row_select"
618
- - "column_width_resize"
619
- - "double_click_column_resize"
620
- - "row_width_resize"
621
- - "column_height_resize"
622
- - "arrowkeys" # all arrowkeys including page up and down
623
- - "up"
624
- - "down"
625
- - "left"
626
- - "right"
627
- - "prior" # page up
628
- - "next" # page down
629
- - "row_height_resize"
630
- - "double_click_row_resize"
631
- - "right_click_popup_menu" / "rc_popup_menu" / "rc_menu"
632
- - "rc_select"
633
- - "rc_insert_column"
634
- - "rc_delete_column"
635
- - "rc_insert_row"
636
- - "rc_delete_row"
637
- - "sort_cells"
638
- - "sort_row"
639
- - "sort_column" / "sort_col"
640
- - "sort_rows"
641
- - "sort_columns" / "sort_cols"
642
- - "ctrl_click_select" / "ctrl_select"
643
- - "copy"
644
- - "cut"
645
- - "paste"
646
- - "delete"
647
- - "undo"
648
- - "find"
649
- - "edit_cell"
650
- - "edit_header"
651
- - "edit_index"
652
- """
653
618
  self.MT.enable_bindings(bindings)
654
619
  return self
655
620
 
656
621
  def disable_bindings(self, *bindings: Binding) -> Sheet:
657
- """
658
- List of available bindings:
659
- - "all"
660
- - "single_select"
661
- - "toggle_select"
662
- - "drag_select"
663
- - "select_all"
664
- - "column_drag_and_drop" / "move_columns"
665
- - "row_drag_and_drop" / "move_rows"
666
- - "column_select"
667
- - "row_select"
668
- - "column_width_resize"
669
- - "double_click_column_resize"
670
- - "row_width_resize"
671
- - "column_height_resize"
672
- - "arrowkeys" # all arrowkeys including page up and down
673
- - "up"
674
- - "down"
675
- - "left"
676
- - "right"
677
- - "prior" # page up
678
- - "next" # page down
679
- - "row_height_resize"
680
- - "double_click_row_resize"
681
- - "right_click_popup_menu" / "rc_popup_menu" / "rc_menu"
682
- - "rc_select"
683
- - "rc_insert_column"
684
- - "rc_delete_column"
685
- - "rc_insert_row"
686
- - "rc_delete_row"
687
- - "ctrl_click_select" / "ctrl_select"
688
- - "copy"
689
- - "cut"
690
- - "paste"
691
- - "delete"
692
- - "undo"
693
- - "find"
694
- - "edit_cell"
695
- - "edit_header"
696
- - "edit_index"
697
- """
698
622
  self.MT.disable_bindings(bindings)
699
623
  return self
700
624
 
@@ -703,76 +627,15 @@ class Sheet(tk.Frame):
703
627
  bindings: ExtraBinding | Sequence[ExtraBinding] | None = None,
704
628
  func: Callable | None = None,
705
629
  ) -> Sheet:
706
- """
707
- List of available bindings:
708
- - "begin_sort_cells"
709
- - "sort_cells", "end_sort_cells"
710
- - "begin_sort_rows"
711
- - "sort_rows", "end_sort_rows"
712
- - "begin_sort_columns"
713
- - "sort_columns", "end_sort_columns"
714
- - "begin_copy", "begin_ctrl_c"
715
- - "ctrl_c", "end_copy", "end_ctrl_c", "copy"
716
- - "begin_cut", "begin_ctrl_x"
717
- - "ctrl_x", "end_cut", "end_ctrl_x", "cut"
718
- - "begin_paste", "begin_ctrl_v"
719
- - "ctrl_v", "end_paste", "end_ctrl_v", "paste"
720
- - "begin_undo", "begin_ctrl_z"
721
- - "ctrl_z", "end_undo", "end_ctrl_z", "undo"
722
- - "begin_delete_key", "begin_delete"
723
- - "delete_key", "end_delete", "end_delete_key", "delete"
724
- - "begin_edit_cell", "begin_edit_table"
725
- - "end_edit_cell", "edit_cell", "edit_table"
726
- - "begin_edit_header"
727
- - "end_edit_header", "edit_header"
728
- - "begin_edit_index"
729
- - "end_edit_index", "edit_index"
730
- - "begin_row_index_drag_drop", "begin_move_rows"
731
- - "row_index_drag_drop", "move_rows", "end_move_rows", "end_row_index_drag_drop"
732
- - "begin_column_header_drag_drop", "begin_move_columns"
733
- - "column_header_drag_drop", "move_columns", "end_move_columns", "end_column_header_drag_drop"
734
- - "begin_rc_delete_row", "begin_delete_rows"
735
- - "rc_delete_row", "end_rc_delete_row", "end_delete_rows", "delete_rows"
736
- - "begin_rc_delete_column", "begin_delete_columns"
737
- - "rc_delete_column", "end_rc_delete_column","end_delete_columns", "delete_columns"
738
- - "begin_rc_insert_column", "begin_insert_column", "begin_insert_columns", "begin_add_column",
739
- "begin_rc_add_column", "begin_add_columns"
740
- - "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column",
741
- "end_rc_add_column", "end_add_column", "end_add_columns", "add_columns"
742
- - "begin_rc_insert_row", "begin_insert_row", "begin_insert_rows", "begin_rc_add_row", "begin_add_row",
743
- "begin_add_rows"
744
- - "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row",
745
- "end_add_row", "end_add_rows", "add_rows"
746
- - "row_height_resize"
747
- - "column_width_resize"
748
- - "cell_select"
749
- - "select_all"
750
- - "row_select"
751
- - "column_select"
752
- - "drag_select_cells"
753
- - "drag_select_rows"
754
- - "drag_select_columns"
755
- - "shift_cell_select"
756
- - "shift_row_select"
757
- - "shift_column_select"
758
- - "ctrl_cell_select"
759
- - "ctrl_row_select"
760
- - "ctrl_column_select"
761
- - "deselect"
762
- - "all_select_events", "select", "selectevents", "select_events"
763
- - "all_modified_events", "sheetmodified", "sheet_modified", "modified_events", "modified"
764
- - "bind_all"
765
- - "unbind_all"
766
- """
767
630
  # bindings is None, unbind all
768
631
  if bindings is None:
769
632
  bindings = "all"
770
633
  # bindings is str, func arg is None or Callable
771
634
  if isinstance(bindings, str):
772
- iterable = [(bindings, func)]
635
+ iterable = ((bindings, func),)
773
636
  # bindings is list or tuple of strings, func arg is None or Callable
774
637
  elif is_iterable(bindings) and isinstance(bindings[0], str):
775
- iterable = [(b, func) for b in bindings]
638
+ iterable = ((b, func) for b in bindings)
776
639
  # bindings is a list or tuple of two tuples or lists
777
640
  # in this case the func arg is ignored
778
641
  # e.g. [(binding, function), (binding, function), ...]
@@ -781,333 +644,22 @@ class Sheet(tk.Frame):
781
644
 
782
645
  for b, f in iterable:
783
646
  b = b.lower()
784
-
785
647
  if f is not None and b in emitted_events:
786
648
  self.bind(b, f)
787
-
788
- if b in (
789
- "all",
790
- "bind_all",
791
- "unbind_all",
792
- ):
793
- self.MT.extra_begin_sort_cells_func = f
794
- self.CH.ch_extra_begin_sort_rows_func = f
795
- self.RI.ri_extra_begin_sort_cols_func = f
796
- self.MT.extra_begin_ctrl_c_func = f
797
- self.MT.extra_begin_ctrl_x_func = f
798
- self.MT.extra_begin_ctrl_v_func = f
799
- self.MT.extra_begin_ctrl_z_func = f
800
- self.MT.extra_begin_delete_key_func = f
801
- self.RI.ri_extra_begin_drag_drop_func = f
802
- self.CH.ch_extra_begin_drag_drop_func = f
803
- self.MT.extra_begin_del_rows_rc_func = f
804
- self.MT.extra_begin_del_cols_rc_func = f
805
- self.MT.extra_begin_insert_cols_rc_func = f
806
- self.MT.extra_begin_insert_rows_rc_func = f
807
- self.MT.extra_begin_edit_cell_func = f
808
- self.CH.extra_begin_edit_cell_func = f
809
- self.RI.extra_begin_edit_cell_func = f
810
- self.CH.column_width_resize_func = f
811
- self.RI.row_height_resize_func = f
812
-
813
- if b in (
814
- "all",
815
- "bind_all",
816
- "unbind_all",
817
- "all_select_events",
818
- "select",
819
- "selectevents",
820
- "select_events",
821
- ):
822
- self.MT.selection_binding_func = f
823
- self.MT.select_all_binding_func = f
824
- self.RI.selection_binding_func = f
825
- self.CH.selection_binding_func = f
826
- self.MT.drag_selection_binding_func = f
827
- self.RI.drag_selection_binding_func = f
828
- self.CH.drag_selection_binding_func = f
829
- self.MT.shift_selection_binding_func = f
830
- self.RI.shift_selection_binding_func = f
831
- self.CH.shift_selection_binding_func = f
832
- self.MT.ctrl_selection_binding_func = f
833
- self.RI.ctrl_selection_binding_func = f
834
- self.CH.ctrl_selection_binding_func = f
835
- self.MT.deselection_binding_func = f
836
-
837
- if b in (
838
- "all",
839
- "bind_all",
840
- "unbind_all",
841
- "all_modified_events",
842
- "sheetmodified",
843
- "sheet_modified",
844
- "modified_events",
845
- "modified",
846
- ):
847
- self.MT.extra_end_sort_cells_func = f
848
- self.CH.ch_extra_end_sort_rows_func = f
849
- self.RI.ri_extra_end_sort_cols_func = f
850
- self.MT.extra_end_ctrl_c_func = f
851
- self.MT.extra_end_ctrl_x_func = f
852
- self.MT.extra_end_ctrl_v_func = f
853
- self.MT.extra_end_ctrl_z_func = f
854
- self.MT.extra_end_delete_key_func = f
855
- self.RI.ri_extra_end_drag_drop_func = f
856
- self.CH.ch_extra_end_drag_drop_func = f
857
- self.MT.extra_end_del_rows_rc_func = f
858
- self.MT.extra_end_del_cols_rc_func = f
859
- self.MT.extra_end_insert_cols_rc_func = f
860
- self.MT.extra_end_insert_rows_rc_func = f
861
- self.MT.extra_end_edit_cell_func = f
862
- self.CH.extra_end_edit_cell_func = f
863
- self.RI.extra_end_edit_cell_func = f
864
-
865
- if b in ("begin_sort_cells",):
866
- self.MT.extra_begin_sort_cells_func = f
867
-
868
- if b in ("sort_cells", "end_sort_cells"):
869
- self.MT.extra_end_sort_cells_func = f
870
-
871
- if b in ("begin_sort_rows",):
872
- self.CH.ch_extra_begin_sort_rows_func = f
873
-
874
- if b in ("sort_rows", "end_sort_rows"):
875
- self.CH.ch_extra_end_sort_rows_func = f
876
-
877
- if b in ("begin_sort_columns",):
878
- self.RI.ri_extra_begin_sort_cols_func = f
879
-
880
- if b in ("sort_columns", "end_sort_columns"):
881
- self.RI.ri_extra_end_sort_cols_func = f
882
-
883
- if b in (
884
- "begin_copy",
885
- "begin_ctrl_c",
886
- ):
887
- self.MT.extra_begin_ctrl_c_func = f
888
- if b in (
889
- "ctrl_c",
890
- "end_copy",
891
- "end_ctrl_c",
892
- "copy",
893
- ):
894
- self.MT.extra_end_ctrl_c_func = f
895
-
896
- if b in (
897
- "begin_cut",
898
- "begin_ctrl_x",
899
- ):
900
- self.MT.extra_begin_ctrl_x_func = f
901
- if b in (
902
- "ctrl_x",
903
- "end_cut",
904
- "end_ctrl_x",
905
- "cut",
906
- ):
907
- self.MT.extra_end_ctrl_x_func = f
908
-
909
- if b in (
910
- "begin_paste",
911
- "begin_ctrl_v",
912
- ):
913
- self.MT.extra_begin_ctrl_v_func = f
914
- if b in (
915
- "ctrl_v",
916
- "end_paste",
917
- "end_ctrl_v",
918
- "paste",
919
- ):
920
- self.MT.extra_end_ctrl_v_func = f
921
-
922
- if b in (
923
- "begin_undo",
924
- "begin_ctrl_z",
925
- ):
926
- self.MT.extra_begin_ctrl_z_func = f
927
- if b in (
928
- "ctrl_z",
929
- "end_undo",
930
- "end_ctrl_z",
931
- "undo",
932
- ):
933
- self.MT.extra_end_ctrl_z_func = f
934
-
935
- if b in (
936
- "begin_delete_key",
937
- "begin_delete",
938
- ):
939
- self.MT.extra_begin_delete_key_func = f
940
- if b in (
941
- "delete_key",
942
- "end_delete",
943
- "end_delete_key",
944
- "delete",
945
- ):
946
- self.MT.extra_end_delete_key_func = f
947
-
948
- if b in (
949
- "begin_edit_cell",
950
- "begin_edit_table",
951
- ):
952
- self.MT.extra_begin_edit_cell_func = f
953
- if b in (
954
- "end_edit_cell",
955
- "edit_cell",
956
- "edit_table",
957
- ):
958
- self.MT.extra_end_edit_cell_func = f
959
-
960
- if b == "begin_edit_header":
961
- self.CH.extra_begin_edit_cell_func = f
962
- if b in (
963
- "end_edit_header",
964
- "edit_header",
965
- ):
966
- self.CH.extra_end_edit_cell_func = f
967
-
968
- if b == "begin_edit_index":
969
- self.RI.extra_begin_edit_cell_func = f
970
- if b in (
971
- "end_edit_index",
972
- "edit_index",
973
- ):
974
- self.RI.extra_end_edit_cell_func = f
975
-
976
- if b in (
977
- "begin_row_index_drag_drop",
978
- "begin_move_rows",
979
- ):
980
- self.RI.ri_extra_begin_drag_drop_func = f
981
- if b in (
982
- "row_index_drag_drop",
983
- "move_rows",
984
- "end_move_rows",
985
- "end_row_index_drag_drop",
986
- ):
987
- self.RI.ri_extra_end_drag_drop_func = f
988
-
989
- if b in (
990
- "begin_column_header_drag_drop",
991
- "begin_move_columns",
992
- ):
993
- self.CH.ch_extra_begin_drag_drop_func = f
994
- if b in (
995
- "column_header_drag_drop",
996
- "move_columns",
997
- "end_move_columns",
998
- "end_column_header_drag_drop",
999
- ):
1000
- self.CH.ch_extra_end_drag_drop_func = f
1001
-
1002
- if b in (
1003
- "begin_rc_delete_row",
1004
- "begin_delete_rows",
1005
- ):
1006
- self.MT.extra_begin_del_rows_rc_func = f
1007
- if b in (
1008
- "rc_delete_row",
1009
- "end_rc_delete_row",
1010
- "end_delete_rows",
1011
- "delete_rows",
1012
- ):
1013
- self.MT.extra_end_del_rows_rc_func = f
1014
-
1015
- if b in (
1016
- "begin_rc_delete_column",
1017
- "begin_delete_columns",
1018
- ):
1019
- self.MT.extra_begin_del_cols_rc_func = f
1020
- if b in (
1021
- "rc_delete_column",
1022
- "end_rc_delete_column",
1023
- "end_delete_columns",
1024
- "delete_columns",
1025
- ):
1026
- self.MT.extra_end_del_cols_rc_func = f
1027
-
1028
- if b in (
1029
- "begin_rc_insert_column",
1030
- "begin_insert_column",
1031
- "begin_insert_columns",
1032
- "begin_add_column",
1033
- "begin_rc_add_column",
1034
- "begin_add_columns",
1035
- ):
1036
- self.MT.extra_begin_insert_cols_rc_func = f
1037
- if b in (
1038
- "rc_insert_column",
1039
- "end_rc_insert_column",
1040
- "end_insert_column",
1041
- "end_insert_columns",
1042
- "rc_add_column",
1043
- "end_rc_add_column",
1044
- "end_add_column",
1045
- "end_add_columns",
1046
- "add_columns",
1047
- ):
1048
- self.MT.extra_end_insert_cols_rc_func = f
1049
-
1050
- if b in (
1051
- "begin_rc_insert_row",
1052
- "begin_insert_row",
1053
- "begin_insert_rows",
1054
- "begin_rc_add_row",
1055
- "begin_add_row",
1056
- "begin_add_rows",
1057
- ):
1058
- self.MT.extra_begin_insert_rows_rc_func = f
1059
- if b in (
1060
- "rc_insert_row",
1061
- "end_rc_insert_row",
1062
- "end_insert_row",
1063
- "end_insert_rows",
1064
- "rc_add_row",
1065
- "end_rc_add_row",
1066
- "end_add_row",
1067
- "end_add_rows",
1068
- "add_rows",
1069
- ):
1070
- self.MT.extra_end_insert_rows_rc_func = f
1071
-
1072
- if b == "column_width_resize":
1073
- self.CH.column_width_resize_func = f
1074
- if b == "row_height_resize":
1075
- self.RI.row_height_resize_func = f
1076
-
1077
- if b == "cell_select":
1078
- self.MT.selection_binding_func = f
1079
- if b in (
1080
- "select_all",
1081
- "ctrl_a",
1082
- ):
1083
- self.MT.select_all_binding_func = f
1084
- if b == "row_select":
1085
- self.RI.selection_binding_func = f
1086
- if b in (
1087
- "col_select",
1088
- "column_select",
1089
- ):
1090
- self.CH.selection_binding_func = f
1091
- if b == "drag_select_cells":
1092
- self.MT.drag_selection_binding_func = f
1093
- if b == "drag_select_rows":
1094
- self.RI.drag_selection_binding_func = f
1095
- if b == "drag_select_columns":
1096
- self.CH.drag_selection_binding_func = f
1097
- if b == "shift_cell_select":
1098
- self.MT.shift_selection_binding_func = f
1099
- if b == "shift_row_select":
1100
- self.RI.shift_selection_binding_func = f
1101
- if b == "shift_column_select":
1102
- self.CH.shift_selection_binding_func = f
1103
- if b == "ctrl_cell_select":
1104
- self.MT.ctrl_selection_binding_func = f
1105
- if b == "ctrl_row_select":
1106
- self.RI.ctrl_selection_binding_func = f
1107
- if b == "ctrl_column_select":
1108
- self.CH.ctrl_selection_binding_func = f
1109
- if b == "deselect":
1110
- self.MT.deselection_binding_func = f
649
+ # Handle group bindings
650
+ if b in ("all", "bind_all", "unbind_all"):
651
+ for component, attr in ALL_BINDINGS:
652
+ setattr(getattr(self, component), attr, f)
653
+ elif b in ("all_select_events", "select", "selectevents", "select_events"):
654
+ for component, attr in SELECT_BINDINGS:
655
+ setattr(getattr(self, component), attr, f)
656
+ elif b in ("all_modified_events", "sheetmodified", "sheet_modified", "modified_events", "modified"):
657
+ for component, attr in MODIFIED_BINDINGS:
658
+ setattr(getattr(self, component), attr, f)
659
+ # Handle individual bindings
660
+ elif b in BINDING_TO_ATTR:
661
+ component, attr = BINDING_TO_ATTR[b]
662
+ setattr(getattr(self, component), attr, f)
1111
663
  return self
1112
664
 
1113
665
  def bind(
@@ -1214,9 +766,17 @@ class Sheet(tk.Frame):
1214
766
  return self
1215
767
 
1216
768
  def edit_validation(self, func: Callable | None = None) -> Sheet:
769
+ if not isinstance(func, (Callable, None)):
770
+ raise ValueError("Argument must be either Callable or None.")
1217
771
  self.MT.edit_validation_func = func
1218
772
  return self
1219
773
 
774
+ def bulk_table_edit_validation(self, func: Callable | None = None) -> Sheet:
775
+ if not isinstance(func, (Callable, None)):
776
+ raise ValueError("Argument must be either Callable or None.")
777
+ self.MT.bulk_table_edit_validation_func = func
778
+ return self
779
+
1220
780
  def popup_menu_add_command(
1221
781
  self,
1222
782
  label: str,
@@ -2671,6 +2231,90 @@ class Sheet(tk.Frame):
2671
2231
  ) -> EventDataDict:
2672
2232
  return self.RI._sort_columns_by_row(row=row, reverse=reverse, key=key, undo=undo)
2673
2233
 
2234
+ # Find and Replace
2235
+
2236
+ @property
2237
+ def find_open(self) -> bool:
2238
+ return self.MT.find_window.open
2239
+
2240
+ def open_find(self, focus: bool = False) -> Sheet:
2241
+ self.MT.open_find_window(focus=focus)
2242
+ return self
2243
+
2244
+ def close_find(self) -> Sheet:
2245
+ self.MT.close_find_window()
2246
+ return self
2247
+
2248
+ def next_match(self, within: bool | None = None, find: str | None = None) -> Sheet:
2249
+ self.MT.find_next(within=within, find=find)
2250
+ return self
2251
+
2252
+ def prev_match(self, within: bool | None = None, find: str | None = None) -> Sheet:
2253
+ self.MT.find_previous(within=within, find=find)
2254
+ return self
2255
+
2256
+ def replace_all(self, mapping: dict[str, str], within: bool = False) -> EventDataDict:
2257
+ event_data = self.MT.new_event_dict("edit_table", boxes=self.MT.get_boxes())
2258
+ if within:
2259
+ iterable = chain.from_iterable(
2260
+ (
2261
+ box_gen_coords(
2262
+ *box.coords,
2263
+ start_r=box.coords.from_r,
2264
+ start_c=box.coords.from_c,
2265
+ reverse=False,
2266
+ all_rows_displayed=self.MT.all_rows_displayed,
2267
+ all_cols_displayed=self.MT.all_columns_displayed,
2268
+ displayed_rows=self.MT.displayed_rows,
2269
+ displayed_cols=self.MT.displayed_columns,
2270
+ )
2271
+ for box in self.MT.selection_boxes.values()
2272
+ )
2273
+ )
2274
+ else:
2275
+ iterable = box_gen_coords(
2276
+ from_r=0,
2277
+ from_c=0,
2278
+ upto_r=self.MT.total_data_rows(include_index=False),
2279
+ upto_c=self.MT.total_data_cols(include_header=False),
2280
+ start_r=0,
2281
+ start_c=0,
2282
+ reverse=False,
2283
+ )
2284
+ for r, c in iterable:
2285
+ for find, replace in mapping.items():
2286
+ m = self.MT.find_match(find, r, c)
2287
+ if (
2288
+ m
2289
+ and not within
2290
+ or (
2291
+ within
2292
+ and (self.MT.all_rows_displayed or bisect_in(self.MT.displayed_rows, r))
2293
+ and (self.MT.all_columns_displayed or bisect_in(self.MT.displayed_columns, c))
2294
+ )
2295
+ ):
2296
+ current = f"{self.MT.get_cell_data(r, c, True)}"
2297
+ new = sub(escape(find), replacer(find, replace, current), current, flags=IGNORECASE)
2298
+ if not self.MT.edit_validation_func or (
2299
+ self.MT.edit_validation_func
2300
+ and (new := self.MT.edit_validation_func(mod_event_val(event_data, new, (r, c)))) is not None
2301
+ ):
2302
+ event_data = self.MT.event_data_set_cell(
2303
+ r,
2304
+ c,
2305
+ new,
2306
+ event_data,
2307
+ )
2308
+ event_data = self.MT.bulk_edit_validation(event_data)
2309
+ if event_data["cells"]["table"]:
2310
+ self.MT.refresh()
2311
+ if self.MT.undo_enabled:
2312
+ self.MT.undo_stack.append(stored_event_dict(event_data))
2313
+ try_binding(self.MT.extra_end_replace_all_func, event_data)
2314
+ self.MT.sheet_modified(event_data)
2315
+ self.emit_event("<<SheetModified>>", event_data)
2316
+ return event_data
2317
+
2674
2318
  # Highlighting Cells
2675
2319
 
2676
2320
  def highlight(
@@ -4451,6 +4095,10 @@ class Sheet(tk.Frame):
4451
4095
 
4452
4096
  # Cell Text Editor
4453
4097
 
4098
+ def next_cell(self, r: int, c: int, key: Literal["Return", "Tab", "??"]) -> Sheet:
4099
+ self.MT.go_to_next_cell(r, c, key)
4100
+ return self
4101
+
4454
4102
  # works on currently selected box
4455
4103
  def open_cell(self, ignore_existing_editor: bool = True) -> Sheet:
4456
4104
  self.MT.open_cell(event=GeneratedMouseEvent(), ignore_existing_editor=ignore_existing_editor)
@@ -4533,13 +4181,16 @@ class Sheet(tk.Frame):
4533
4181
  # Sheet Options and Other Functions
4534
4182
 
4535
4183
  def set_options(self, redraw: bool = True, **kwargs) -> Sheet:
4184
+ enabled = tuple(self.MT.enabled_bindings)
4536
4185
  for k, v in kwargs.items():
4537
4186
  if k in self.ops and v != self.ops[k]:
4538
4187
  if k.endswith("bindings"):
4539
- self.MT._disable_binding(k.split("_")[0])
4188
+ for b in enabled:
4189
+ self.MT._disable_binding(b)
4540
4190
  self.ops[k] = v
4541
4191
  if k.endswith("bindings"):
4542
- self.MT._enable_binding(k.split("_")[0])
4192
+ for b in enabled:
4193
+ self.MT._enable_binding(b)
4543
4194
  if "name" in kwargs:
4544
4195
  self.name = kwargs["name"]
4545
4196
  if "min_column_width" in kwargs:
@@ -5238,14 +4889,6 @@ class Sheet(tk.Frame):
5238
4889
  """
5239
4890
  if item not in self.RI.tree:
5240
4891
  raise ValueError(f"Item '{item}' does not exist.")
5241
- if isinstance(iid, str):
5242
- if iid in self.RI.tree:
5243
- raise ValueError(f"Cannot rename '{iid}', it already exists.")
5244
- self.RI.tree[item].iid = iid
5245
- self.RI.tree[iid] = self.RI.tree.pop(item)
5246
- self.RI.tree_rns[iid] = self.RI.tree_rns.pop(item)
5247
- if iid in self.RI.tree_open_ids:
5248
- self.RI.tree_open_ids[iid] = self.RI.tree_open_ids.pop(item)
5249
4892
  if isinstance(text, str):
5250
4893
  self.RI.tree[item].text = text
5251
4894
  if isinstance(values, list):
@@ -5273,6 +4916,21 @@ class Sheet(tk.Frame):
5273
4916
  )
5274
4917
  else:
5275
4918
  self.RI.tree_open_ids.discard(item)
4919
+ if isinstance(iid, str):
4920
+ if iid in self.RI.tree:
4921
+ raise ValueError(f"Cannot rename '{iid}', it already exists.")
4922
+ for ciid in self.RI.tree[item].children:
4923
+ self.RI.tree[ciid].parent = iid
4924
+ if self.RI.tree[item].parent:
4925
+ parent_node = self.RI.parent_node(item)
4926
+ item_index = parent_node.children.index(item)
4927
+ parent_node.children[item_index] = iid
4928
+ self.RI.tree[item].iid = iid
4929
+ self.RI.tree[iid] = self.RI.tree.pop(item)
4930
+ self.RI.tree_rns[iid] = self.RI.tree_rns.pop(item)
4931
+ if item in self.RI.tree_open_ids:
4932
+ self.RI.tree_open_ids.discard(item)
4933
+ self.RI.tree_open_ids.add(iid)
5276
4934
  get = not (isinstance(iid, str) or isinstance(text, str) or isinstance(values, list) or isinstance(open_, bool))
5277
4935
  self.set_refresh_timer(redraw=not get and redraw)
5278
4936
  if get:
@@ -5413,9 +5071,7 @@ class Sheet(tk.Frame):
5413
5071
  - Unlike the ttk treeview 'see' function
5414
5072
  this function does **NOT** scroll to the item
5415
5073
  """
5416
- if item not in self.RI.tree:
5417
- raise ValueError(f"Item '{item}' does not exist.")
5418
- if self.RI.tree[item].parent:
5074
+ if not self.item_displayed(item) and self.RI.tree[item].parent:
5419
5075
  self.show_rows(
5420
5076
  rows=self._tree_open(list(self.RI.get_iid_ancestors(item))),
5421
5077
  redraw=False,
@@ -5427,8 +5083,6 @@ class Sheet(tk.Frame):
5427
5083
  """
5428
5084
  Scrolls to an item and ensures that it is displayed
5429
5085
  """
5430
- if item not in self.RI.tree:
5431
- raise ValueError(f"Item '{item}' does not exist.")
5432
5086
  self.display_item(item, redraw=False)
5433
5087
  self.see(
5434
5088
  row=bisect_left(self.MT.displayed_rows, self.RI.tree_rns[item]),
@@ -5649,7 +5303,10 @@ class Sheet(tk.Frame):
5649
5303
  # ########## OLD FUNCTIONS ##########
5650
5304
 
5651
5305
  def get_cell_data(self, r: int, c: int, get_displayed: bool = False) -> Any:
5652
- return self.MT.get_cell_data(r, c, get_displayed)
5306
+ if get_displayed:
5307
+ return self.MT.get_valid_cell_data_as_str(r, c, get_displayed=True)
5308
+ else:
5309
+ return self.MT.get_cell_data(r, c)
5653
5310
 
5654
5311
  def get_row_data(
5655
5312
  self,
@@ -5670,12 +5327,11 @@ class Sheet(tk.Frame):
5670
5327
  total_data_cols = self.MT.total_data_cols()
5671
5328
  self.MT.fix_data_len(r, total_data_cols - 1)
5672
5329
  iterable = only_columns if only_columns is not None else range(len(self.MT.data[r]))
5330
+ f = partial(self.MT.get_valid_cell_data_as_str, get_displayed=True) if get_displayed else self.MT.get_cell_data
5673
5331
  if get_index:
5674
- return [self.get_index_data(r, get_displayed=get_index_displayed)] + [
5675
- self.MT.get_cell_data(r, c, get_displayed=get_displayed) for c in iterable
5676
- ]
5332
+ return [self.get_index_data(r, get_displayed=get_index_displayed)] + [f(r, c) for c in iterable]
5677
5333
  else:
5678
- return [self.MT.get_cell_data(r, c, get_displayed=get_displayed) for c in iterable]
5334
+ return [f(r, c) for c in iterable]
5679
5335
 
5680
5336
  def get_column_data(
5681
5337
  self,
@@ -5691,8 +5347,9 @@ class Sheet(tk.Frame):
5691
5347
  elif not is_iterable(only_rows):
5692
5348
  raise ValueError(tksheet_type_error("only_rows", ["int", "iterable", "None"], only_rows))
5693
5349
  iterable = only_rows if only_rows is not None else range(len(self.MT.data))
5350
+ f = partial(self.MT.get_valid_cell_data_as_str, get_displayed=True) if get_displayed else self.MT.get_cell_data
5694
5351
  return ([self.get_header_data(c, get_displayed=get_header_displayed)] if get_header else []) + [
5695
- self.MT.get_cell_data(r, c, get_displayed=get_displayed) for r in iterable
5352
+ f(r, c) for r in iterable
5696
5353
  ]
5697
5354
 
5698
5355
  def get_sheet_data(