tksheet 7.3.1__py3-none-any.whl → 7.3.2__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/main_table.py CHANGED
@@ -39,6 +39,22 @@ from typing import Literal
39
39
  from .colors import (
40
40
  color_map,
41
41
  )
42
+ from .constants import (
43
+ USER_OS,
44
+ bind_add_columns,
45
+ bind_add_rows,
46
+ bind_del_columns,
47
+ bind_del_rows,
48
+ ctrl_key,
49
+ rc_binding,
50
+ text_editor_close_bindings,
51
+ text_editor_newline_bindings,
52
+ text_editor_to_unbind,
53
+ val_modifying_options,
54
+ )
55
+ from .find_window import (
56
+ FindWindow,
57
+ )
42
58
  from .formatters import (
43
59
  data_to_str,
44
60
  format_data,
@@ -50,6 +66,7 @@ from .formatters import (
50
66
  from .functions import (
51
67
  add_to_displayed,
52
68
  b_index,
69
+ bisect_in,
53
70
  box_is_single_cell,
54
71
  cell_right_within_box,
55
72
  color_tup,
@@ -58,6 +75,8 @@ from .functions import (
58
75
  diff_list,
59
76
  down_cell_within_box,
60
77
  event_dict,
78
+ event_has_char_key,
79
+ event_opens_dropdown_or_checkbox,
61
80
  float_to_int,
62
81
  gen_formatted,
63
82
  get_data_from_clipboard,
@@ -86,6 +105,7 @@ from .other_classes import (
86
105
  Box_t,
87
106
  DotDict,
88
107
  DropdownStorage,
108
+ EditorStorageBase,
89
109
  EventDataDict,
90
110
  FontTuple,
91
111
  Highlight,
@@ -101,20 +121,6 @@ from .text_editor import (
101
121
  from .types import (
102
122
  AnyIter,
103
123
  )
104
- from .vars import (
105
- USER_OS,
106
- bind_add_columns,
107
- bind_add_rows,
108
- bind_del_columns,
109
- bind_del_rows,
110
- ctrl_key,
111
- rc_binding,
112
- symbols_set,
113
- text_editor_close_bindings,
114
- text_editor_newline_bindings,
115
- text_editor_to_unbind,
116
- val_modifying_options,
117
- )
118
124
 
119
125
 
120
126
  class MainTable(tk.Canvas):
@@ -140,6 +146,7 @@ class MainTable(tk.Canvas):
140
146
  self.synced_scrolls = set()
141
147
  self.dropdown = DropdownStorage()
142
148
  self.text_editor = TextEditorStorage()
149
+ self.find_window = EditorStorageBase()
143
150
  self.event_linker = {
144
151
  "<<Copy>>": self.ctrl_c,
145
152
  "<<Cut>>": self.ctrl_x,
@@ -248,6 +255,7 @@ class MainTable(tk.Canvas):
248
255
  self.drag_selection_enabled = False
249
256
  self.select_all_enabled = False
250
257
  self.undo_enabled = False
258
+ self.find_enabled = False
251
259
  self.cut_enabled = False
252
260
  self.copy_enabled = False
253
261
  self.paste_enabled = False
@@ -476,6 +484,250 @@ class MainTable(tk.Canvas):
476
484
  if delete_on_timer:
477
485
  self.after(1500, self.delete_ctrl_outlines)
478
486
 
487
+ def escape(self, event: tk.Misc | None) -> None:
488
+ if self.find_window.open:
489
+ self.close_find_window()
490
+ else:
491
+ self.deselect()
492
+
493
+ def get_find_window_dimensions_coords(self, w_width: int) -> tuple[int, int, int, int]:
494
+ width = min(self.get_txt_w("X" * 23), w_width - 7)
495
+ # w, h, x, y
496
+ return width, self.min_row_height, self.canvasx(max(0, w_width - width - 7)), self.canvasy(7)
497
+
498
+ def open_find_window(
499
+ self,
500
+ event: tk.Misc | None = None,
501
+ focus: bool = True,
502
+ ) -> Literal["break"]:
503
+ if self.find_window.open:
504
+ self.close_find_window()
505
+ return "break"
506
+ width, height, x, y = self.get_find_window_dimensions_coords(w_width=self.winfo_width())
507
+ if not self.find_window.window:
508
+ self.find_window.window = FindWindow(
509
+ self,
510
+ find_prev_func=self.find_previous,
511
+ find_next_func=self.find_next,
512
+ close_func=self.close_find_window,
513
+ )
514
+ self.find_window.canvas_id = self.create_window((x, y), window=self.find_window.window, anchor="nw")
515
+ for b in chain(self.PAR.ops.escape_bindings, self.PAR.ops.find_bindings):
516
+ self.find_window.tktext.bind(b, self.close_find_window)
517
+ for b in chain(self.PAR.ops.find_next_bindings, ("<Return>", "<KP_Enter>")):
518
+ self.find_window.tktext.bind(b, self.find_next)
519
+ for b in self.PAR.ops.find_previous_bindings:
520
+ self.find_window.tktext.bind(b, self.find_previous)
521
+ else:
522
+ self.coords(self.find_window.canvas_id, x, y)
523
+ if not self.find_window.open:
524
+ self.itemconfig(self.find_window.canvas_id, state="normal")
525
+ self.find_window.open = True
526
+ self.find_window.window.reset(
527
+ **{
528
+ "menu_kwargs": DotDict(
529
+ {
530
+ "font": self.PAR.ops.table_font,
531
+ "foreground": self.PAR.ops.popup_menu_fg,
532
+ "background": self.PAR.ops.popup_menu_bg,
533
+ "activebackground": self.PAR.ops.popup_menu_highlight_bg,
534
+ "activeforeground": self.PAR.ops.popup_menu_highlight_fg,
535
+ }
536
+ ),
537
+ "sheet_ops": self.PAR.ops,
538
+ "border_color": self.PAR.ops.table_selected_box_cells_fg,
539
+ "bg": self.PAR.ops.table_editor_bg,
540
+ "fg": self.PAR.ops.table_editor_fg,
541
+ "select_bg": self.PAR.ops.table_editor_select_bg,
542
+ "select_fg": self.PAR.ops.table_editor_select_fg,
543
+ }
544
+ )
545
+ self.itemconfig(self.find_window.canvas_id, width=width, height=height)
546
+ if focus:
547
+ self.find_window.tktext.focus_set()
548
+ return "break"
549
+
550
+ def find_see_and_set(self, coords: tuple[int, int] | None, just_see: bool = False) -> tuple[int, int]:
551
+ if coords:
552
+ if not self.all_rows_displayed:
553
+ coords = (self.disprn(coords[0]), coords[1])
554
+ if not self.all_columns_displayed:
555
+ coords = (coords[0], self.dispcn(coords[1]))
556
+ if not just_see:
557
+ if self.find_window.window.find_in_selection:
558
+ self.set_currently_selected(*coords)
559
+ else:
560
+ self.select_cell(*coords, redraw=False)
561
+ if not self.see(
562
+ *coords,
563
+ keep_yscroll=False,
564
+ keep_xscroll=False,
565
+ bottom_right_corner=False,
566
+ check_cell_visibility=True,
567
+ redraw=True,
568
+ ):
569
+ self.refresh()
570
+ return coords
571
+
572
+ def find_gen_all_cells(
573
+ self,
574
+ start_row: int,
575
+ start_col: int,
576
+ total_cols: int | None = None,
577
+ reverse: bool = False,
578
+ ) -> Generator[tuple[int, int]]:
579
+ if total_cols is None:
580
+ total_cols = self.total_data_cols(include_header=False)
581
+ total_rows = self.total_data_rows(include_index=False)
582
+ if reverse:
583
+ # yield start cell
584
+ yield (start_row, start_col)
585
+ # yield any remaining cells in the starting row before the start column
586
+ if start_col:
587
+ for col in reversed(range(start_col)):
588
+ yield (start_row, col)
589
+ # yield any cells above start row
590
+ for row in reversed(range(start_row)):
591
+ for col in reversed(range(total_cols)):
592
+ yield (row, col)
593
+ # yield cells from bottom of table upward
594
+ for row in range(total_rows - 1, start_row, -1):
595
+ for col in reversed(range(total_cols)):
596
+ yield (row, col)
597
+ # yield any remaining cells in start row
598
+ for col in range(total_cols - 1, start_col, -1):
599
+ yield (start_row, col)
600
+ else:
601
+ # Yield cells from the start position to the end of the current row
602
+ for col in range(start_col, total_cols):
603
+ yield (start_row, col)
604
+ # yield from the next row to the last row
605
+ for row in range(start_row + 1, total_rows):
606
+ for col in range(total_cols):
607
+ yield (row, col)
608
+ # yield from the beginning up to the start
609
+ for row in range(start_row):
610
+ for col in range(total_cols):
611
+ yield (row, col)
612
+ # yield any remaining cells in the starting row before the start column
613
+ for col in range(start_col):
614
+ yield (start_row, col)
615
+
616
+ def find_get_start_coords(
617
+ self,
618
+ plus_one: bool = True,
619
+ within: None | list = None,
620
+ reverse: bool = False,
621
+ ) -> tuple[int, int, int]:
622
+ selected = self.selected
623
+ if not selected:
624
+ return 0, 0, 0
625
+ max_row = len(self.row_positions) - 2
626
+ max_col = len(self.col_positions) - 2
627
+ row, col = selected.row, selected.column
628
+ if plus_one and within:
629
+ curridx = bisect_left(within, (row, col)) + (1 if not reverse else -1)
630
+ return row, col, curridx % len(within)
631
+ if plus_one:
632
+ if reverse:
633
+ if col == 0:
634
+ col = max_col
635
+ row = max_row if row == 0 else row - 1
636
+ else:
637
+ col -= 1
638
+ else:
639
+ col = (col + 1) % (max_col + 1)
640
+ if col == 0:
641
+ row = (row + 1) % (max_row + 1)
642
+ return row, col, 0
643
+
644
+ def find_match(self, find: str, r: int, c: int) -> bool:
645
+ return (
646
+ not find
647
+ and (not self.get_valid_cell_data_as_str(r, c, True).lower() or not f"{self.get_cell_data(r, c)}".lower())
648
+ ) or (
649
+ find
650
+ and (
651
+ find in self.get_valid_cell_data_as_str(r, c, True).lower()
652
+ or find in f"{self.get_cell_data(r, c)}".lower()
653
+ )
654
+ )
655
+
656
+ def find_within_sels(
657
+ self,
658
+ find: str,
659
+ reverse: bool = False,
660
+ ) -> tuple[int, int] | None:
661
+ sels = self.PAR.get_selected_cells(
662
+ get_rows=True,
663
+ get_columns=True,
664
+ sort_by_row=True,
665
+ sort_by_column=True,
666
+ )
667
+ _, _, from_idx = self.find_get_start_coords(plus_one=True, within=sels, reverse=reverse)
668
+ for r, c in chain(islice(sels, from_idx, None), islice(sels, 0, from_idx)):
669
+ if not self.all_rows_displayed:
670
+ r = self.datarn(r)
671
+ if not self.all_columns_displayed:
672
+ c = self.datacn(c)
673
+ if self.find_match(find, r, c):
674
+ return (r, c)
675
+ return None
676
+
677
+ def find_all_cells(
678
+ self,
679
+ find: str,
680
+ reverse: bool = False,
681
+ ) -> tuple[int, int] | None:
682
+ row, col, _ = self.find_get_start_coords(plus_one=True, reverse=reverse)
683
+ row, col = self.datarn(row), self.datacn(col)
684
+ return next(
685
+ (
686
+ (r, c)
687
+ for r, c in self.find_gen_all_cells(
688
+ start_row=row,
689
+ start_col=col,
690
+ total_cols=self.total_data_cols(include_header=False),
691
+ reverse=reverse,
692
+ )
693
+ if (
694
+ (self.all_rows_displayed or bisect_in(self.displayed_rows, r))
695
+ and (self.all_columns_displayed or bisect_in(self.displayed_columns, c))
696
+ and self.find_match(find, r, c)
697
+ )
698
+ ),
699
+ None,
700
+ )
701
+
702
+ def find_next(self, event: tk.Misc | None = None) -> Literal["break"]:
703
+ find = self.find_window.get().lower()
704
+ if not self.find_window.open:
705
+ self.open_find_window(focus=False)
706
+ if self.find_window.window.find_in_selection:
707
+ self.find_see_and_set(self.find_within_sels(find))
708
+ else:
709
+ self.find_see_and_set(self.find_all_cells(find))
710
+ return "break"
711
+
712
+ def find_previous(self, event: tk.Misc | None = None) -> Literal["break"]:
713
+ find = self.find_window.get().lower()
714
+ if not self.find_window.open:
715
+ self.open_find_window(focus=False)
716
+ if self.find_window.window.find_in_selection:
717
+ self.find_see_and_set(self.find_within_sels(find, reverse=True))
718
+ else:
719
+ self.find_see_and_set(self.find_all_cells(find, reverse=True))
720
+ return "break"
721
+
722
+ def close_find_window(
723
+ self,
724
+ event: tk.Misc | None = None,
725
+ ) -> None:
726
+ if self.find_window.open:
727
+ self.itemconfig(self.find_window.canvas_id, state="hidden")
728
+ self.find_window.open = False
729
+ self.focus_set()
730
+
479
731
  def create_ctrl_outline(
480
732
  self,
481
733
  x1: int,
@@ -527,19 +779,19 @@ class MainTable(tk.Canvas):
527
779
  self.hidd_ctrl_outline[t] = False
528
780
 
529
781
  def get_ctrl_x_c_boxes(self) -> tuple[dict[tuple[int, int, int, int], str], int]:
530
- boxes = {}
531
782
  maxrows = 0
532
783
  if not self.selected:
533
- return boxes, maxrows
784
+ return {}, maxrows
534
785
  if self.selected.type_ in ("cells", "columns"):
535
786
  curr_box = self.selection_boxes[self.selected.fill_iid].coords
536
787
  maxrows = curr_box[2] - curr_box[0]
537
- for item, box in self.get_selection_items(rows=False):
538
- if maxrows >= box.coords[2] - box.coords[0]:
539
- boxes[box.coords] = box.type_
788
+ boxes = {
789
+ box.coords: box.type_
790
+ for _, box in self.get_selection_items(rows=False)
791
+ if maxrows >= box.coords[2] - box.coords[0]
792
+ }
540
793
  else:
541
- for item, box in self.get_selection_items(columns=False, cells=False):
542
- boxes[box.coords] = "rows"
794
+ boxes = {box.coords: "rows" for _, box in self.get_selection_items(columns=False, cells=False)}
543
795
  return boxes, maxrows
544
796
 
545
797
  def io_csv_writer(self) -> tuple[io.StringIO, csv.writer]:
@@ -1750,23 +2002,23 @@ class MainTable(tk.Canvas):
1750
2002
  y = self.row_positions[r]
1751
2003
  else:
1752
2004
  y = self.row_positions[r + 1] + 1 - winfo_height
2005
+ y = y / (self.row_positions[-1] + self.PAR.ops.empty_vertical)
1753
2006
  args = [
1754
2007
  "moveto",
1755
- y / (self.row_positions[-1] + self.PAR.ops.empty_vertical),
2008
+ y - 1 if y > 1 else y,
1756
2009
  ]
1757
- if args[1] > 1:
1758
- args[1] = args[1] - 1
1759
2010
  self.set_yviews(*args, redraw=False)
1760
2011
  need_redraw = True
1761
2012
  else:
1762
2013
  if r is not None and not keep_yscroll:
1763
- y = self.row_positions[r] + ((self.row_positions[r + 1] - self.row_positions[r]) * r_pc)
2014
+ y = int(self.row_positions[r] + ((self.row_positions[r + 1] - self.row_positions[r]) * r_pc)) - 2
2015
+ if y < 0:
2016
+ y = 0
2017
+ y = y / (self.row_positions[-1] + self.PAR.ops.empty_vertical)
1764
2018
  args = [
1765
2019
  "moveto",
1766
- y / (self.row_positions[-1] + self.PAR.ops.empty_vertical),
2020
+ y - 1 if y > 1 else y,
1767
2021
  ]
1768
- if args[1] > 1:
1769
- args[1] = args[1] - 1
1770
2022
  self.set_yviews(*args, redraw=False)
1771
2023
  need_redraw = True
1772
2024
  if not xvis and len(self.col_positions) > 1:
@@ -1777,18 +2029,22 @@ class MainTable(tk.Canvas):
1777
2029
  x = self.col_positions[c]
1778
2030
  else:
1779
2031
  x = self.col_positions[c + 1] + 1 - winfo_width
2032
+ x = x / (self.col_positions[-1] + self.PAR.ops.empty_horizontal)
1780
2033
  args = [
1781
2034
  "moveto",
1782
- x / (self.col_positions[-1] + self.PAR.ops.empty_horizontal),
2035
+ x - 1 if x > 1 else x,
1783
2036
  ]
1784
2037
  self.set_xviews(*args, redraw=False)
1785
2038
  need_redraw = True
1786
2039
  else:
1787
2040
  if c is not None and not keep_xscroll:
1788
- x = self.col_positions[c] + ((self.col_positions[c + 1] - self.col_positions[c]) * c_pc)
2041
+ x = int(self.col_positions[c] + ((self.col_positions[c + 1] - self.col_positions[c]) * c_pc)) - 2
2042
+ if x < 0:
2043
+ x = 0
2044
+ x = x / (self.col_positions[-1] + self.PAR.ops.empty_horizontal)
1789
2045
  args = [
1790
2046
  "moveto",
1791
- x / (self.col_positions[-1] + self.PAR.ops.empty_horizontal),
2047
+ x - 1 if x > 1 else x,
1792
2048
  ]
1793
2049
  self.set_xviews(*args, redraw=False)
1794
2050
  need_redraw = True
@@ -1810,20 +2066,12 @@ class MainTable(tk.Canvas):
1810
2066
  r: int | None = 0,
1811
2067
  c: int | None = 0,
1812
2068
  separate_axes: bool = False,
1813
- ) -> bool:
2069
+ ) -> bool | tuple[bool, bool]:
1814
2070
  cx1, cy1, cx2, cy2 = self.get_canvas_visible_area()
1815
2071
  x1, y1, x2, y2 = self.get_cell_coords(r, c)
1816
- x_vis = True
1817
- y_vis = True
1818
- if cx1 > x1 or cx2 < x2:
1819
- x_vis = False
1820
- if cy1 > y1 or cy2 < y2:
1821
- y_vis = False
1822
- if separate_axes:
1823
- return y_vis, x_vis
1824
- if not y_vis or not x_vis:
1825
- return False
1826
- return True
2072
+ x_vis = cx1 <= x1 and cx2 >= x2
2073
+ y_vis = cy1 <= y1 and cy2 >= y2
2074
+ return (y_vis, x_vis) if separate_axes else y_vis and x_vis
1827
2075
 
1828
2076
  def cell_visible(self, r: int = 0, c: int = 0) -> bool:
1829
2077
  cx1, cy1, cx2, cy2 = self.get_canvas_visible_area()
@@ -1877,13 +2125,13 @@ class MainTable(tk.Canvas):
1877
2125
 
1878
2126
  def select_row_start(self, event: object) -> None:
1879
2127
  if self.selected:
1880
- self.select_cell(self.selected.row, 0)
1881
2128
  self.see(self.selected.row, 0)
2129
+ self.select_cell(self.selected.row, 0, redraw=True)
1882
2130
 
1883
2131
  def select_a1(self, event: object) -> None:
1884
2132
  if len(self.row_positions) > 1 and len(self.col_positions) > 1:
1885
- self.select_cell(0, 0)
1886
2133
  self.see(0, 0)
2134
+ self.select_cell(0, 0, redraw=True)
1887
2135
 
1888
2136
  def select_cell(
1889
2137
  self,
@@ -2213,9 +2461,8 @@ class MainTable(tk.Canvas):
2213
2461
  elif self.selected.type_ in ("cells", "columns"):
2214
2462
  r = self.selected.row
2215
2463
  c = self.selected.column
2216
- if not r and self.CH.col_selection_enabled:
2217
- if not self.cell_completely_visible(r=r, c=0):
2218
- self.see(r, c, check_cell_visibility=False)
2464
+ if not r and self.CH.col_selection_enabled and not self.cell_completely_visible(r=r, c=c):
2465
+ self.see(r, c, check_cell_visibility=False)
2219
2466
  elif r and (self.single_selection_enabled or self.toggle_selection_enabled):
2220
2467
  if self.cell_completely_visible(r=r - 1, c=c):
2221
2468
  self.select_cell(r - 1, c, redraw=True)
@@ -2229,32 +2476,18 @@ class MainTable(tk.Canvas):
2229
2476
  if self.selected.type_ == "rows":
2230
2477
  r = self.selected.row
2231
2478
  if r < len(self.row_positions) - 2 and self.RI.row_selection_enabled:
2232
- if self.cell_completely_visible(r=min(r + 2, len(self.row_positions) - 2), c=0):
2479
+ if self.cell_completely_visible(r=r + 1, c=0):
2233
2480
  self.RI.select_row(r + 1, redraw=True)
2234
2481
  else:
2235
2482
  self.RI.select_row(r + 1)
2236
- if (
2237
- r + 2 < len(self.row_positions) - 2
2238
- and (self.row_positions[r + 3] - self.row_positions[r + 2])
2239
- + (self.row_positions[r + 2] - self.row_positions[r + 1])
2240
- + 5
2241
- < self.winfo_height()
2242
- ):
2243
- self.see(
2244
- r + 2,
2245
- 0,
2246
- keep_xscroll=True,
2247
- bottom_right_corner=True,
2248
- check_cell_visibility=False,
2249
- )
2250
- elif not self.cell_completely_visible(r=r + 1, c=0):
2251
- self.see(
2252
- r + 1,
2253
- 0,
2254
- keep_xscroll=True,
2255
- bottom_right_corner=False if self.PAR.ops.arrow_key_down_right_scroll_page else True,
2256
- check_cell_visibility=False,
2257
- )
2483
+ self.see(
2484
+ r + 1,
2485
+ 0,
2486
+ keep_xscroll=True,
2487
+ bottom_right_corner=False if self.PAR.ops.arrow_key_down_right_scroll_page else True,
2488
+ check_cell_visibility=False,
2489
+ )
2490
+
2258
2491
  elif self.selected.type_ == "columns":
2259
2492
  c = self.selected.column
2260
2493
  if self.single_selection_enabled or self.toggle_selection_enabled:
@@ -2275,32 +2508,17 @@ class MainTable(tk.Canvas):
2275
2508
  r = self.selected.row
2276
2509
  c = self.selected.column
2277
2510
  if r < len(self.row_positions) - 2 and (self.single_selection_enabled or self.toggle_selection_enabled):
2278
- if self.cell_completely_visible(r=min(r + 2, len(self.row_positions) - 2), c=c):
2511
+ if self.cell_completely_visible(r=r + 1, c=c):
2279
2512
  self.select_cell(r + 1, c, redraw=True)
2280
2513
  else:
2281
2514
  self.select_cell(r + 1, c)
2282
- if (
2283
- r + 2 < len(self.row_positions) - 2
2284
- and (self.row_positions[r + 3] - self.row_positions[r + 2])
2285
- + (self.row_positions[r + 2] - self.row_positions[r + 1])
2286
- + 5
2287
- < self.winfo_height()
2288
- ):
2289
- self.see(
2290
- r + 2,
2291
- c,
2292
- keep_xscroll=True,
2293
- bottom_right_corner=True,
2294
- check_cell_visibility=False,
2295
- )
2296
- elif not self.cell_completely_visible(r=r + 1, c=c):
2297
- self.see(
2298
- r + 1,
2299
- c,
2300
- keep_xscroll=True,
2301
- bottom_right_corner=False if self.PAR.ops.arrow_key_down_right_scroll_page else True,
2302
- check_cell_visibility=False,
2303
- )
2515
+ self.see(
2516
+ r + 1,
2517
+ c,
2518
+ keep_xscroll=True,
2519
+ bottom_right_corner=False if self.PAR.ops.arrow_key_down_right_scroll_page else True,
2520
+ check_cell_visibility=False,
2521
+ )
2304
2522
 
2305
2523
  def arrowkey_LEFT(self, event: object = None) -> None:
2306
2524
  if not self.selected:
@@ -2325,7 +2543,7 @@ class MainTable(tk.Canvas):
2325
2543
  elif self.selected.type_ == "cells":
2326
2544
  r = self.selected.row
2327
2545
  c = self.selected.column
2328
- if not c and not self.cell_completely_visible(r=r, c=0):
2546
+ if not c and not self.cell_completely_visible(r=r, c=c):
2329
2547
  self.see(r, c, keep_yscroll=True, check_cell_visibility=False)
2330
2548
  elif c and (self.single_selection_enabled or self.toggle_selection_enabled):
2331
2549
  if self.cell_completely_visible(r=r, c=c - 1):
@@ -2710,7 +2928,7 @@ class MainTable(tk.Canvas):
2710
2928
  **mnkwgs,
2711
2929
  )
2712
2930
 
2713
- def enable_bindings(self, bindings):
2931
+ def enable_bindings(self, bindings: object) -> None:
2714
2932
  if not bindings:
2715
2933
  self._enable_binding("all")
2716
2934
  elif isinstance(bindings, (list, tuple)):
@@ -2752,6 +2970,7 @@ class MainTable(tk.Canvas):
2752
2970
  ):
2753
2971
  self._tksheet_bind("row_start_bindings", self.select_row_start)
2754
2972
  self._tksheet_bind("table_start_bindings", self.select_a1)
2973
+ self._tksheet_bind("escape_bindings", self.escape)
2755
2974
  if binding in ("all", "single", "single_selection_mode", "single_select"):
2756
2975
  self.single_selection_enabled = True
2757
2976
  self.toggle_selection_enabled = False
@@ -2829,6 +3048,11 @@ class MainTable(tk.Canvas):
2829
3048
  self.undo_enabled = True
2830
3049
  self._tksheet_bind("undo_bindings", self.undo)
2831
3050
  self._tksheet_bind("redo_bindings", self.redo)
3051
+ if binding in ("find",):
3052
+ self.find_enabled = True
3053
+ self._tksheet_bind("find_bindings", self.open_find_window)
3054
+ self._tksheet_bind("find_next_bindings", self.find_next)
3055
+ self._tksheet_bind("find_previous_bindings", self.find_previous)
2832
3056
  if binding in bind_del_columns:
2833
3057
  self.rc_delete_column_enabled = True
2834
3058
  self.rc_popup_menus_enabled = True
@@ -2881,6 +3105,7 @@ class MainTable(tk.Canvas):
2881
3105
  ):
2882
3106
  self._tksheet_unbind("row_start_bindings")
2883
3107
  self._tksheet_unbind("table_start_bindings")
3108
+ self._tksheet_unbind("escape_bindings")
2884
3109
  self.single_selection_enabled = False
2885
3110
  self.toggle_selection_enabled = False
2886
3111
  if binding in ("all", "drag_select"):
@@ -2971,6 +3196,12 @@ class MainTable(tk.Canvas):
2971
3196
  if binding in ("all", "undo", "redo", "edit_bindings", "edit"):
2972
3197
  self.undo_enabled = False
2973
3198
  self._tksheet_unbind("undo_bindings", "redo_bindings")
3199
+ if binding in ("all", "find"):
3200
+ self.find_enabled = False
3201
+ self._tksheet_unbind("find_bindings")
3202
+ self._tksheet_unbind("find_next_bindings")
3203
+ self._tksheet_unbind("find_previous_bindings")
3204
+ self.close_find_window()
2974
3205
 
2975
3206
  def _tksheet_unbind(self, *keys) -> None:
2976
3207
  for widget in (self, self.RI, self.CH, self.TL):
@@ -3457,26 +3688,42 @@ class MainTable(tk.Canvas):
3457
3688
  if move_synced:
3458
3689
  self.y_move_synced_scrolls(*args, use_scrollbar=True)
3459
3690
 
3460
- def set_xviews(self, *args, move_synced: bool = True, redraw: bool = True) -> None:
3691
+ def set_xviews(
3692
+ self,
3693
+ *args,
3694
+ move_synced: bool = True,
3695
+ redraw: bool = True,
3696
+ ) -> None:
3461
3697
  self.main_table_redraw_grid_and_text(setting_views=True)
3462
- self.update_idletasks()
3698
+ if not self.PAR._startup_complete:
3699
+ self.update_idletasks()
3463
3700
  self.xview(*args)
3464
3701
  if self.show_header:
3465
- self.CH.update_idletasks()
3702
+ if not self.PAR._startup_complete:
3703
+ self.CH.update_idletasks()
3466
3704
  self.CH.xview(*args)
3467
- self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=False)
3705
+ if redraw:
3706
+ self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=False)
3468
3707
  if move_synced:
3469
3708
  self.x_move_synced_scrolls(*args)
3470
3709
  self.fix_views()
3471
3710
 
3472
- def set_yviews(self, *args, move_synced: bool = True, redraw: bool = True) -> None:
3711
+ def set_yviews(
3712
+ self,
3713
+ *args,
3714
+ move_synced: bool = True,
3715
+ redraw: bool = True,
3716
+ ) -> None:
3473
3717
  self.main_table_redraw_grid_and_text(setting_views=True)
3474
- self.update_idletasks()
3718
+ if not self.PAR._startup_complete:
3719
+ self.update_idletasks()
3475
3720
  self.yview(*args)
3476
3721
  if self.show_index:
3477
- self.RI.update_idletasks()
3722
+ if not self.PAR._startup_complete:
3723
+ self.RI.update_idletasks()
3478
3724
  self.RI.yview(*args)
3479
- self.main_table_redraw_grid_and_text(redraw_header=False, redraw_row_index=True)
3725
+ if redraw:
3726
+ self.main_table_redraw_grid_and_text(redraw_header=False, redraw_row_index=True)
3480
3727
  if move_synced:
3481
3728
  self.y_move_synced_scrolls(*args)
3482
3729
  self.fix_views()
@@ -3618,7 +3865,7 @@ class MainTable(tk.Canvas):
3618
3865
  b = self.txt_measure_canvas.bbox(self.txt_measure_canvas_text)
3619
3866
  return b[3] - b[1]
3620
3867
 
3621
- def get_txt_dimensions(self, txt: str, font: None | FontTuple = None) -> int:
3868
+ def get_txt_dimensions(self, txt: str, font: None | FontTuple = None) -> tuple[int, int]:
3622
3869
  self.txt_measure_canvas.itemconfig(
3623
3870
  self.txt_measure_canvas_text,
3624
3871
  text=txt,
@@ -3639,7 +3886,6 @@ class MainTable(tk.Canvas):
3639
3886
  def set_min_column_width(self, width: int) -> None:
3640
3887
  if width:
3641
3888
  self.PAR.ops.min_column_width = width
3642
-
3643
3889
  if self.PAR.ops.min_column_width > self.PAR.ops.max_column_width:
3644
3890
  self.PAR.ops.max_column_width = self.PAR.ops.min_column_width + 20
3645
3891
  if (
@@ -3669,12 +3915,12 @@ class MainTable(tk.Canvas):
3669
3915
  def set_table_font(self, newfont: tuple | None = None, reset_row_positions: bool = False) -> tuple[str, int, str]:
3670
3916
  if newfont:
3671
3917
  if not isinstance(newfont, tuple):
3672
- raise ValueError("Argument must be tuple e.g. " "('Carlito', 12, 'normal')")
3918
+ raise ValueError("Argument must be tuple e.g. ('Carlito', 12, 'normal')")
3673
3919
  if len(newfont) != 3:
3674
3920
  raise ValueError("Argument must be three-tuple")
3675
3921
  if not isinstance(newfont[0], str) or not isinstance(newfont[1], int) or not isinstance(newfont[2], str):
3676
3922
  raise ValueError(
3677
- "Argument must be font, size and 'normal', 'bold' or" "'italic' e.g. ('Carlito',12,'normal')"
3923
+ "Argument must be font, size and 'normal', 'bold' or'italic' e.g. ('Carlito',12,'normal')"
3678
3924
  )
3679
3925
  self.PAR.ops.table_font = FontTuple(*newfont)
3680
3926
  self.set_table_font_help()
@@ -3706,7 +3952,7 @@ class MainTable(tk.Canvas):
3706
3952
  raise ValueError("Argument must be three-tuple")
3707
3953
  if not isinstance(newfont[0], str) or not isinstance(newfont[1], int) or not isinstance(newfont[2], str):
3708
3954
  raise ValueError(
3709
- "Argument must be font, size and 'normal', 'bold' or" "'italic' e.g. ('Carlito',12,'normal')"
3955
+ "Argument must be font, size and 'normal', 'bold' or'italic' e.g. ('Carlito',12,'normal')"
3710
3956
  )
3711
3957
  self.PAR.ops.header_font = FontTuple(*newfont)
3712
3958
  self.set_header_font_help()
@@ -3737,7 +3983,7 @@ class MainTable(tk.Canvas):
3737
3983
  raise ValueError("Argument must be three-tuple")
3738
3984
  if not isinstance(newfont[0], str) or not isinstance(newfont[1], int) or not isinstance(newfont[2], str):
3739
3985
  raise ValueError(
3740
- "Argument must be font, size and 'normal', 'bold' or" "'italic' e.g. ('Carlito',12,'normal')"
3986
+ "Argument must be font, size and 'normal', 'bold' or'italic' e.g. ('Carlito',12,'normal')"
3741
3987
  )
3742
3988
  self.PAR.ops.index_font = FontTuple(*newfont)
3743
3989
  self.set_index_font_help()
@@ -4752,8 +4998,8 @@ class MainTable(tk.Canvas):
4752
4998
  data_ins_col: int,
4753
4999
  displayed_ins_col: int,
4754
5000
  numcols: int,
4755
- columns: list | None = None,
4756
- widths: list | None = None,
5001
+ columns: list[list[object]] | None = None,
5002
+ widths: list[int] | tuple[int] | None = None,
4757
5003
  headers: bool = False,
4758
5004
  ) -> tuple[dict, dict, dict]:
4759
5005
  header_data = {}
@@ -4802,10 +5048,10 @@ class MainTable(tk.Canvas):
4802
5048
  data_ins_row: int,
4803
5049
  displayed_ins_row: int,
4804
5050
  numrows: int,
4805
- rows: list | None = None,
4806
- heights: list | None = None,
5051
+ rows: list[list[object]] | None = None,
5052
+ heights: list[int] | tuple[int] | None = None,
4807
5053
  row_index: bool = False,
4808
- total_data_cols=None,
5054
+ total_data_cols: int | None = None,
4809
5055
  ) -> tuple[dict, dict, dict]:
4810
5056
  index_data = {}
4811
5057
  if isinstance(self._row_index, list):
@@ -5008,7 +5254,7 @@ class MainTable(tk.Canvas):
5008
5254
 
5009
5255
  def display_rows(
5010
5256
  self,
5011
- rows: int | AnyIter | None = None,
5257
+ rows: int | AnyIter[int] | None = None,
5012
5258
  all_rows_displayed: bool | None = None,
5013
5259
  reset_row_positions: bool = True,
5014
5260
  deselect_all: bool = True,
@@ -5037,7 +5283,7 @@ class MainTable(tk.Canvas):
5037
5283
 
5038
5284
  def display_columns(
5039
5285
  self,
5040
- columns: int | AnyIter | None = None,
5286
+ columns: int | AnyIter[int] | None = None,
5041
5287
  all_columns_displayed: bool | None = None,
5042
5288
  reset_col_positions: bool = True,
5043
5289
  deselect_all: bool = True,
@@ -5642,11 +5888,18 @@ class MainTable(tk.Canvas):
5642
5888
  if resized_cols or resized_rows or changed_w:
5643
5889
  self.recreate_all_selection_boxes()
5644
5890
  if changed_w:
5645
- self.update_idletasks()
5646
- self.RI.update_idletasks()
5647
- self.CH.update_idletasks()
5648
- self.TL.update_idletasks()
5891
+ for widget in (self, self.RI, self.CH, self.TL):
5892
+ widget.update_idletasks()
5649
5893
  return False
5894
+ if self.find_window.open:
5895
+ w, h, x, y = self.get_find_window_dimensions_coords(w_width=self.winfo_width())
5896
+ self.coords(self.find_window.canvas_id, x, y)
5897
+ self.itemconfig(
5898
+ self.find_window.canvas_id,
5899
+ width=w,
5900
+ height=h,
5901
+ state="normal",
5902
+ )
5650
5903
  self.hidd_text.update(self.disp_text)
5651
5904
  self.disp_text = {}
5652
5905
  self.hidd_high.update(self.disp_high)
@@ -5677,13 +5930,13 @@ class MainTable(tk.Canvas):
5677
5930
  chain.from_iterable(
5678
5931
  [
5679
5932
  (
5680
- self.canvasx(0) - 1,
5933
+ scrollpos_left - 1,
5681
5934
  self.row_positions[r],
5682
5935
  x_grid_stop,
5683
5936
  self.row_positions[r],
5684
- self.canvasx(0) - 1,
5937
+ scrollpos_left - 1,
5685
5938
  self.row_positions[r],
5686
- self.canvasx(0) - 1,
5939
+ scrollpos_left - 1,
5687
5940
  self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
5688
5941
  )
5689
5942
  for r in range(grid_start_row, grid_end_row)
@@ -6045,56 +6298,35 @@ class MainTable(tk.Canvas):
6045
6298
  box: tuple[int, int, int, int] | None = None,
6046
6299
  run_binding: bool = True,
6047
6300
  ) -> None:
6301
+ def box_created(r: int, c: int, box: SelectionBox) -> bool:
6302
+ r1, c1, r2, c2 = box.coords
6303
+ if r1 <= r and c1 <= c and r2 >= r and c2 >= c:
6304
+ self.create_currently_selected_box(r, c, box.type_, box.fill_iid)
6305
+ if run_binding:
6306
+ self.run_selection_binding(box.type_)
6307
+ return True
6308
+ return False
6309
+
6310
+ # set current to a particular existing selection box
6048
6311
  if isinstance(item, int) and item in self.selection_boxes:
6049
6312
  selection_box = self.selection_boxes[item]
6050
6313
  r1, c1, r2, c2 = selection_box.coords
6051
- if r is None:
6052
- r = r1
6053
- if c is None:
6054
- c = c1
6055
- if r1 <= r and c1 <= c and r2 >= r and c2 >= c:
6056
- self.create_currently_selected_box(
6057
- r,
6058
- c,
6059
- selection_box.type_,
6060
- selection_box.fill_iid,
6061
- )
6062
- if run_binding:
6063
- self.run_selection_binding(selection_box.type_)
6314
+ if box_created(r1 if r is None else r, c1 if c is None else c, selection_box):
6064
6315
  return
6065
- # currently selected is pointed at any selection box with "box" coordinates
6316
+
6317
+ # set current to any existing selection box with coordinates: box
6066
6318
  if isinstance(box, tuple):
6067
- if r is None:
6068
- r = box[0]
6069
- if c is None:
6070
- c = box[1]
6071
6319
  for item, selection_box in self.get_selection_items(reverse=True):
6072
- r1, c1, r2, c2 = selection_box.coords
6073
- if box == (r1, c1, r2, c2) and r1 <= r and c1 <= c and r2 >= r and c2 >= c:
6074
- self.create_currently_selected_box(
6075
- r,
6076
- c,
6077
- selection_box.type_,
6078
- selection_box.fill_iid,
6079
- )
6080
- if run_binding:
6081
- self.run_selection_binding(selection_box.type_)
6082
- return
6083
- # currently selected is just pointed at a coordinate
6084
- # find the top most box there, requires r and c
6085
- if r is not None and c is not None:
6320
+ if box == selection_box.coords:
6321
+ if box_created(box[0] if r is None else r, box[1] if c is None else c, selection_box):
6322
+ return
6323
+
6324
+ # set current to a coordinate, find the top most box there
6325
+ if isinstance(r, int) and isinstance(c, int):
6086
6326
  for item, selection_box in self.get_selection_items(reverse=True):
6087
- r1, c1, r2, c2 = selection_box.coords
6088
- if r1 <= r and c1 <= c and r2 >= r and c2 >= c:
6089
- self.create_currently_selected_box(
6090
- r,
6091
- c,
6092
- selection_box.type_,
6093
- selection_box.fill_iid,
6094
- )
6095
- if run_binding:
6096
- self.run_selection_binding(selection_box.type_)
6327
+ if box_created(r, c, selection_box):
6097
6328
  return
6329
+
6098
6330
  # wasn't provided an item and couldn't find a box at coords so select cell
6099
6331
  if r < len(self.row_positions) - 1 and c < len(self.col_positions) - 1:
6100
6332
  self.select_cell(r, c, redraw=True)
@@ -6215,7 +6447,7 @@ class MainTable(tk.Canvas):
6215
6447
 
6216
6448
  def hide_selection_box(self, item: int | None) -> bool:
6217
6449
  if item is None or item is True or item not in self.selection_boxes:
6218
- return
6450
+ return False
6219
6451
  box = self.selection_boxes.pop(item)
6220
6452
  self.hide_box(box.fill_iid)
6221
6453
  self.hide_box(box.bd_iid)
@@ -6465,50 +6697,30 @@ class MainTable(tk.Canvas):
6465
6697
  def recreate_all_selection_boxes(self) -> None:
6466
6698
  if not self.selected:
6467
6699
  return
6700
+
6468
6701
  modified = False
6702
+ row_limit = len(self.row_positions) - 1
6703
+ col_limit = len(self.col_positions) - 1
6704
+
6469
6705
  for item, box in self.get_selection_items():
6470
6706
  r1, c1, r2, c2 = box.coords
6471
- if not modified:
6472
- modified = (
6473
- r1 >= len(self.row_positions) - 1
6474
- or c1 >= len(self.col_positions) - 1
6475
- or r2 > len(self.row_positions) - 1
6476
- or c2 > len(self.col_positions) - 1
6477
- )
6478
- if r1 >= len(self.row_positions) - 1:
6479
- if len(self.row_positions) > 1:
6480
- r1 = len(self.row_positions) - 2
6481
- else:
6482
- r1 = 0
6483
- if c1 >= len(self.col_positions) - 1:
6484
- if len(self.col_positions) > 1:
6485
- c1 = len(self.col_positions) - 2
6486
- else:
6487
- c1 = 0
6488
- if r2 > len(self.row_positions) - 1:
6489
- r2 = len(self.row_positions) - 1
6490
- if c2 > len(self.col_positions) - 1:
6491
- c2 = len(self.col_positions) - 1
6707
+ # check coordinates
6708
+ r1 = min(r1, row_limit - (1 if row_limit > 0 else 0))
6709
+ c1 = min(c1, col_limit - (1 if col_limit > 0 else 0))
6710
+ r2 = min(r2, row_limit)
6711
+ c2 = min(c2, col_limit)
6712
+
6713
+ modified = modified or (r1 >= row_limit or c1 >= col_limit or r2 > row_limit or c2 > col_limit)
6492
6714
  self.recreate_selection_box(r1, c1, r2, c2, item, run_binding=False)
6493
6715
 
6494
6716
  if self.selected:
6495
- r = self.selected.row
6496
- c = self.selected.column
6497
- if r < len(self.row_positions) - 1 and c < len(self.col_positions) - 1:
6498
- self.set_currently_selected(
6499
- r,
6500
- c,
6501
- item=self.selected.fill_iid,
6502
- run_binding=False,
6503
- )
6717
+ r, c = self.selected.row, self.selected.column
6718
+ if r < row_limit and c < col_limit:
6719
+ self.set_currently_selected(r, c, item=self.selected.fill_iid, run_binding=False)
6504
6720
  else:
6505
6721
  box = self.selection_boxes[self.selected.fill_iid]
6506
- self.set_currently_selected(
6507
- box.coords.from_r,
6508
- box.coords.from_c,
6509
- item=box.fill_iid,
6510
- run_binding=False,
6511
- )
6722
+ self.set_currently_selected(box.coords[0], box.coords[1], item=box.fill_iid, run_binding=False)
6723
+
6512
6724
  if modified:
6513
6725
  self.PAR.emit_event(
6514
6726
  "<<SheetSelect>>",
@@ -6535,23 +6747,17 @@ class MainTable(tk.Canvas):
6535
6747
  return d
6536
6748
 
6537
6749
  def get_selected_min_max(self) -> tuple[int, int, int, int] | tuple[None, None, None, None]:
6538
- min_x = float("inf")
6539
- min_y = float("inf")
6540
- max_x = 0
6541
- max_y = 0
6542
- for item, box in self.get_selection_items():
6750
+ if not self.get_selection_items():
6751
+ return None, None, None, None
6752
+ min_y, min_x = float("inf"), float("inf")
6753
+ max_y, max_x = 0, 0
6754
+
6755
+ for _, box in self.get_selection_items():
6543
6756
  r1, c1, r2, c2 = box.coords
6544
- if r1 < min_y:
6545
- min_y = r1
6546
- if c1 < min_x:
6547
- min_x = c1
6548
- if r2 > max_y:
6549
- max_y = r2
6550
- if c2 > max_x:
6551
- max_x = c2
6552
- if min_x != float("inf") and min_y != float("inf") and max_x > 0 and max_y > 0:
6553
- return min_y, min_x, max_y, max_x
6554
- return None, None, None, None
6757
+ min_y, min_x = min(min_y, r1), min(min_x, c1)
6758
+ max_y, max_x = max(max_y, r2), max(max_x, c2)
6759
+
6760
+ return (min_y, min_x, max_y, max_x) if min_y != float("inf") else (None, None, None, None)
6555
6761
 
6556
6762
  def get_selected_rows(
6557
6763
  self,
@@ -6706,7 +6912,7 @@ class MainTable(tk.Canvas):
6706
6912
  elif self.get_cell_kwargs(datarn, datacn, key="dropdown") or self.get_cell_kwargs(
6707
6913
  datarn, datacn, key="checkbox"
6708
6914
  ):
6709
- if self.event_opens_dropdown_or_checkbox(event):
6915
+ if event_opens_dropdown_or_checkbox(event):
6710
6916
  if self.get_cell_kwargs(datarn, datacn, key="dropdown"):
6711
6917
  self.open_dropdown_window(r, c, event=event)
6712
6918
  elif self.get_cell_kwargs(datarn, datacn, key="checkbox"):
@@ -6714,27 +6920,6 @@ class MainTable(tk.Canvas):
6714
6920
  else:
6715
6921
  self.open_text_editor(event=event, r=r, c=c, dropdown=False)
6716
6922
 
6717
- def event_opens_dropdown_or_checkbox(self, event=None) -> bool:
6718
- if event is None:
6719
- return False
6720
- elif event == "rc":
6721
- return True
6722
- elif (
6723
- (hasattr(event, "keysym") and event.keysym == "Return")
6724
- or (hasattr(event, "keysym") and event.keysym == "F2")
6725
- or (
6726
- event is not None
6727
- and hasattr(event, "keycode")
6728
- and event.keycode == "??"
6729
- and hasattr(event, "num")
6730
- and event.num == 1
6731
- ) # mouseclick
6732
- or (hasattr(event, "keysym") and event.keysym == "BackSpace")
6733
- ):
6734
- return True
6735
- else:
6736
- return False
6737
-
6738
6923
  # displayed indexes
6739
6924
  def get_cell_align(self, r: int, c: int) -> str:
6740
6925
  datarn = self.datarn(r)
@@ -6754,27 +6939,16 @@ class MainTable(tk.Canvas):
6754
6939
  state: str = "normal",
6755
6940
  dropdown: bool = False,
6756
6941
  ) -> bool:
6757
- text = None
6942
+ text = f"{self.get_cell_data(self.datarn(r), self.datacn(c), none_to_empty_str=True)}"
6758
6943
  extra_func_key = "??"
6759
- if event is None or self.event_opens_dropdown_or_checkbox(event):
6760
- if event is not None:
6761
- if hasattr(event, "keysym") and event.keysym == "Return":
6762
- extra_func_key = "Return"
6763
- elif hasattr(event, "keysym") and event.keysym == "F2":
6764
- extra_func_key = "F2"
6765
- if event is not None and (hasattr(event, "keysym") and event.keysym == "BackSpace"):
6766
- extra_func_key = "BackSpace"
6767
- text = ""
6768
- else:
6769
- text = f"{self.get_cell_data(self.datarn(r), self.datacn(c), none_to_empty_str = True)}"
6770
- elif event is not None and (
6771
- (hasattr(event, "char") and event.char.isalpha())
6772
- or (hasattr(event, "char") and event.char.isdigit())
6773
- or (hasattr(event, "char") and event.char in symbols_set)
6774
- ):
6775
- extra_func_key = event.char
6776
- text = event.char
6777
- else:
6944
+ if event_opens_dropdown_or_checkbox(event):
6945
+ if hasattr(event, "keysym") and event.keysym in ("Return", "F2", "BackSpace"):
6946
+ extra_func_key = event.keysym
6947
+ if event.keysym == "BackSpace":
6948
+ text = ""
6949
+ elif event_has_char_key(event):
6950
+ extra_func_key = text = event.char
6951
+ elif event is not None:
6778
6952
  return False
6779
6953
  if self.extra_begin_edit_cell_func:
6780
6954
  try:
@@ -6797,12 +6971,11 @@ class MainTable(tk.Canvas):
6797
6971
  return False
6798
6972
  else:
6799
6973
  text = text if isinstance(text, str) else f"{text}"
6800
- text = "" if text is None else text
6801
6974
  if self.PAR.ops.cell_auto_resize_enabled:
6802
6975
  self.set_cell_size_to_text(r, c, only_if_too_small=True, redraw=True, run_binding=True)
6803
6976
  if self.text_editor.open and (r, c) == self.text_editor.coords:
6804
6977
  self.text_editor.window.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
6805
- return
6978
+ return False
6806
6979
  self.hide_text_editor()
6807
6980
  if not self.see(r=r, c=c, check_cell_visibility=True):
6808
6981
  self.refresh()
@@ -6810,8 +6983,6 @@ class MainTable(tk.Canvas):
6810
6983
  y = self.row_positions[r]
6811
6984
  w = self.col_positions[c + 1] - x + 1
6812
6985
  h = self.row_positions[r + 1] - y + 1
6813
- if text is None:
6814
- text = f"{self.get_cell_data(self.datarn(r), self.datacn(c), none_to_empty_str = True)}"
6815
6986
  kwargs = {
6816
6987
  "menu_kwargs": DotDict(
6817
6988
  {