tksheet 7.2.22__py3-none-any.whl → 7.3.0__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
@@ -59,6 +59,7 @@ from .functions import (
59
59
  diff_list,
60
60
  down_cell_within_box,
61
61
  event_dict,
62
+ float_to_int,
62
63
  gen_formatted,
63
64
  get_data_from_clipboard,
64
65
  get_new_indexes,
@@ -257,8 +258,6 @@ class MainTable(tk.Canvas):
257
258
  self.rc_insert_row_enabled = False
258
259
  self.rc_popup_menus_enabled = False
259
260
  self.edit_cell_enabled = False
260
- self.new_row_width = 0
261
- self.new_header_height = 0
262
261
  self.CH = kwargs["column_headers_canvas"]
263
262
  self.CH.MT = self
264
263
  self.CH.RI = kwargs["row_index_canvas"]
@@ -297,11 +296,6 @@ class MainTable(tk.Canvas):
297
296
  self.txt_measure_canvas = tk.Canvas(self)
298
297
  self.txt_measure_canvas_text = self.txt_measure_canvas.create_text(0, 0, text="", font=self.PAR.ops.table_font)
299
298
 
300
- self.max_row_height = float(kwargs["max_row_height"])
301
- self.max_index_width = float(kwargs["max_index_width"])
302
- self.max_column_width = float(kwargs["max_column_width"])
303
- self.max_header_height = float(kwargs["max_header_height"])
304
-
305
299
  self.RI.set_width(self.PAR.ops.default_row_index_width)
306
300
  self.set_table_font_help()
307
301
  self.set_header_font_help()
@@ -1514,25 +1508,49 @@ class MainTable(tk.Canvas):
1514
1508
  self.purge_redo_stack()
1515
1509
 
1516
1510
  def edit_cells_using_modification(self, modification: dict, event_data: dict) -> EventDataDict:
1511
+ # row index
1517
1512
  if self.PAR.ops.treeview:
1518
1513
  for datarn, v in modification["cells"]["index"].items():
1519
- self._row_index[datarn].text = v
1514
+ if not self.edit_validation_func or (
1515
+ self.edit_validation_func
1516
+ and (v := self.edit_validation_func(mod_event_val(event_data, v, row=datarn))) is not None
1517
+ ):
1518
+ self._row_index[datarn].text = v
1520
1519
  else:
1521
1520
  for datarn, v in modification["cells"]["index"].items():
1522
- self._row_index[datarn] = v
1521
+ if not self.edit_validation_func or (
1522
+ self.edit_validation_func
1523
+ and (v := self.edit_validation_func(mod_event_val(event_data, v, row=datarn))) is not None
1524
+ ):
1525
+ self._row_index[datarn] = v
1526
+
1527
+ # header
1523
1528
  for datacn, v in modification["cells"]["header"].items():
1524
- self._headers[datacn] = v
1525
- for (datarn, datacn), v in modification["cells"]["table"].items():
1526
- self.set_cell_data(datarn, datacn, v)
1529
+ if not self.edit_validation_func or (
1530
+ self.edit_validation_func
1531
+ and (v := self.edit_validation_func(mod_event_val(event_data, v, column=datacn))) is not None
1532
+ ):
1533
+ self._headers[datacn] = v
1534
+
1535
+ # table
1536
+ for k, v in modification["cells"]["table"].items():
1537
+ if not self.edit_validation_func or (
1538
+ self.edit_validation_func
1539
+ and (v := self.edit_validation_func(mod_event_val(event_data, v, loc=k))) is not None
1540
+ ):
1541
+ self.set_cell_data(k[0], k[1], v)
1542
+
1527
1543
  return event_data
1528
1544
 
1529
1545
  def save_cells_using_modification(self, modification: EventDataDict, event_data: EventDataDict) -> EventDataDict:
1530
- for datarn, v in modification["cells"]["index"].items():
1546
+ for datarn in modification["cells"]["index"]:
1531
1547
  event_data["cells"]["index"][datarn] = self.RI.get_cell_data(datarn)
1532
- for datacn, v in modification["cells"]["header"].items():
1548
+
1549
+ for datacn in modification["cells"]["header"]:
1533
1550
  event_data["cells"]["header"][datacn] = self.CH.get_cell_data(datacn)
1534
- for (datarn, datacn), v in modification["cells"]["table"].items():
1535
- event_data["cells"]["table"][(datarn, datacn)] = self.get_cell_data(datarn, datacn)
1551
+
1552
+ for k in modification["cells"]["table"]:
1553
+ event_data["cells"]["table"][k] = self.get_cell_data(k[0], k[1])
1536
1554
  return event_data
1537
1555
 
1538
1556
  def restore_options_named_spans(self, modification: EventDataDict) -> None:
@@ -3167,9 +3185,10 @@ class MainTable(tk.Canvas):
3167
3185
  self.b1_motion(event)
3168
3186
 
3169
3187
  def b1_release(self, event=None):
3188
+ to_hide = self.being_drawn_item
3170
3189
  if self.being_drawn_item is not None and (to_sel := self.coords_and_type(self.being_drawn_item)):
3171
3190
  r_to_sel, c_to_sel = self.selected.row, self.selected.column
3172
- self.hide_selection_box(self.being_drawn_item)
3191
+ self.being_drawn_item = None
3173
3192
  self.set_currently_selected(
3174
3193
  r_to_sel,
3175
3194
  c_to_sel,
@@ -3182,26 +3201,9 @@ class MainTable(tk.Canvas):
3182
3201
  ),
3183
3202
  set_current=False,
3184
3203
  ),
3204
+ run_binding=False,
3185
3205
  )
3186
- sel_event = self.get_select_event(being_drawn_item=self.being_drawn_item)
3187
- try_binding(self.drag_selection_binding_func, sel_event)
3188
- self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
3189
- else:
3190
- self.being_drawn_item = None
3191
- if self.RI.width_resizing_enabled and self.RI.rsz_w is not None and self.RI.currently_resizing_width:
3192
- self.delete_resize_lines()
3193
- self.RI.delete_resize_lines()
3194
- self.RI.currently_resizing_width = False
3195
- self.RI.set_width(self.new_row_width, set_TL=True)
3196
- self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
3197
- self.b1_pressed_loc = None
3198
- elif self.CH.height_resizing_enabled and self.CH.rsz_h is not None and self.CH.currently_resizing_height:
3199
- self.delete_resize_lines()
3200
- self.CH.delete_resize_lines()
3201
- self.CH.currently_resizing_height = False
3202
- self.CH.set_height(self.new_header_height, set_TL=True)
3203
- self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
3204
- self.b1_pressed_loc = None
3206
+ self.hide_selection_box(to_hide)
3205
3207
  self.RI.rsz_w = None
3206
3208
  self.CH.rsz_h = None
3207
3209
  if self.b1_pressed_loc is not None:
@@ -3524,7 +3526,7 @@ class MainTable(tk.Canvas):
3524
3526
  c_pc=c_pc,
3525
3527
  )
3526
3528
 
3527
- def get_txt_w(self, txt, font=None):
3529
+ def get_txt_w(self, txt: str, font: None | FontTuple = None) -> int:
3528
3530
  self.txt_measure_canvas.itemconfig(
3529
3531
  self.txt_measure_canvas_text,
3530
3532
  text=txt,
@@ -3533,7 +3535,7 @@ class MainTable(tk.Canvas):
3533
3535
  b = self.txt_measure_canvas.bbox(self.txt_measure_canvas_text)
3534
3536
  return b[2] - b[0]
3535
3537
 
3536
- def get_txt_h(self, txt, font=None):
3538
+ def get_txt_h(self, txt: str, font: None | FontTuple = None) -> int:
3537
3539
  self.txt_measure_canvas.itemconfig(
3538
3540
  self.txt_measure_canvas_text,
3539
3541
  text=txt,
@@ -3542,7 +3544,7 @@ class MainTable(tk.Canvas):
3542
3544
  b = self.txt_measure_canvas.bbox(self.txt_measure_canvas_text)
3543
3545
  return b[3] - b[1]
3544
3546
 
3545
- def get_txt_dimensions(self, txt, font=None):
3547
+ def get_txt_dimensions(self, txt: str, font: None | FontTuple = None) -> int:
3546
3548
  self.txt_measure_canvas.itemconfig(
3547
3549
  self.txt_measure_canvas_text,
3548
3550
  text=txt,
@@ -3551,7 +3553,7 @@ class MainTable(tk.Canvas):
3551
3553
  b = self.txt_measure_canvas.bbox(self.txt_measure_canvas_text)
3552
3554
  return b[2] - b[0], b[3] - b[1]
3553
3555
 
3554
- def get_lines_cell_height(self, n, font=None):
3556
+ def get_lines_cell_height(self, n: int, font: None | FontTuple = None) -> int:
3555
3557
  return (
3556
3558
  self.get_txt_h(
3557
3559
  txt="\n".join("|" for _ in range(n)) if n > 1 else "|",
@@ -3560,15 +3562,17 @@ class MainTable(tk.Canvas):
3560
3562
  + 5
3561
3563
  )
3562
3564
 
3563
- def set_min_column_width(self):
3564
- self.min_column_width = 1
3565
- if self.min_column_width > self.max_column_width:
3566
- self.max_column_width = self.min_column_width + 20
3565
+ def set_min_column_width(self, width: int) -> None:
3566
+ if width:
3567
+ self.PAR.ops.min_column_width = width
3568
+
3569
+ if self.PAR.ops.min_column_width > self.PAR.ops.max_column_width:
3570
+ self.PAR.ops.max_column_width = self.PAR.ops.min_column_width + 20
3567
3571
  if (
3568
3572
  isinstance(self.PAR.ops.auto_resize_columns, (int, float))
3569
- and self.PAR.ops.auto_resize_columns < self.min_column_width
3573
+ and self.PAR.ops.auto_resize_columns < self.PAR.ops.min_column_width
3570
3574
  ):
3571
- self.PAR.ops.auto_resize_columns = self.min_column_width
3575
+ self.PAR.ops.auto_resize_columns = self.PAR.ops.min_column_width
3572
3576
 
3573
3577
  def get_default_row_height(self) -> int:
3574
3578
  if isinstance(self.PAR.ops.default_row_height, str):
@@ -3619,7 +3623,6 @@ class MainTable(tk.Canvas):
3619
3623
  self.table_xtra_lines_increment = int(self.table_txt_height)
3620
3624
  if self.min_row_height < 12:
3621
3625
  self.min_row_height = 12
3622
- self.set_min_column_width()
3623
3626
 
3624
3627
  def set_header_font(self, newfont: tuple | None = None) -> tuple[str, int, str]:
3625
3628
  if newfont:
@@ -3650,7 +3653,6 @@ class MainTable(tk.Canvas):
3650
3653
  and self.PAR.ops.default_header_height < self.min_header_height
3651
3654
  ):
3652
3655
  self.PAR.ops.default_header_height = int(self.min_header_height)
3653
- self.set_min_column_width()
3654
3656
  self.CH.set_height(self.get_default_header_height(), set_TL=True)
3655
3657
 
3656
3658
  def set_index_font(self, newfont: tuple | None = None) -> tuple[str, int, str]:
@@ -3720,15 +3722,15 @@ class MainTable(tk.Canvas):
3720
3722
  w = b[2] - b[0] + 7
3721
3723
  h = b[3] - b[1] + 5
3722
3724
  else:
3723
- w = self.min_column_width
3725
+ w = self.PAR.ops.min_column_width
3724
3726
  h = self.min_row_height
3725
3727
  if self.get_cell_kwargs(datarn, datacn, key="dropdown") or self.get_cell_kwargs(datarn, datacn, key="checkbox"):
3726
3728
  return w + self.table_txt_height, h
3727
3729
  return w, h
3728
3730
 
3729
3731
  def set_cell_size_to_text(self, r, c, only_if_too_small=False, redraw: bool = True, run_binding=False):
3730
- min_column_width = int(self.min_column_width)
3731
- min_rh = int(self.min_row_height)
3732
+ min_column_width = self.PAR.ops.min_column_width
3733
+ min_rh = self.min_row_height
3732
3734
  w = min_column_width
3733
3735
  h = min_rh
3734
3736
  datacn = self.datacn(c)
@@ -3737,13 +3739,13 @@ class MainTable(tk.Canvas):
3737
3739
  if tw > w:
3738
3740
  w = tw
3739
3741
  if h < min_rh:
3740
- h = int(min_rh)
3741
- elif h > self.max_row_height:
3742
- h = int(self.max_row_height)
3742
+ h = min_rh
3743
+ elif h > self.PAR.ops.max_row_height:
3744
+ h = int(self.PAR.ops.max_row_height)
3743
3745
  if w < min_column_width:
3744
- w = int(min_column_width)
3745
- elif w > self.max_column_width:
3746
- w = int(self.max_column_width)
3746
+ w = min_column_width
3747
+ elif w > self.PAR.ops.max_column_width:
3748
+ w = int(self.PAR.ops.max_column_width)
3747
3749
  cell_needs_resize_w = False
3748
3750
  cell_needs_resize_h = False
3749
3751
  if only_if_too_small:
@@ -3803,8 +3805,10 @@ class MainTable(tk.Canvas):
3803
3805
  width: int | None = None,
3804
3806
  slim: bool = False,
3805
3807
  ) -> tuple[list[float], list[float]]:
3806
- min_column_width = int(self.min_column_width)
3807
- min_rh = int(self.min_row_height)
3808
+ min_column_width = self.PAR.ops.min_column_width
3809
+ max_column_width = float_to_int(self.PAR.ops.max_column_width)
3810
+ max_row_height = float_to_int(self.PAR.ops.max_row_height)
3811
+ min_rh = self.min_row_height
3808
3812
  h = min_rh
3809
3813
  rhs = defaultdict(lambda: int(min_rh))
3810
3814
  cws = []
@@ -3827,9 +3831,9 @@ class MainTable(tk.Canvas):
3827
3831
  for datarn in iterrows:
3828
3832
  w_, h = self.RI.get_cell_dimensions(datarn)
3829
3833
  if h < min_rh:
3830
- h = int(min_rh)
3831
- elif h > self.max_row_height:
3832
- h = int(self.max_row_height)
3834
+ h = min_rh
3835
+ elif h > max_row_height:
3836
+ h = max_row_height
3833
3837
  if h > rhs[datarn]:
3834
3838
  rhs[datarn] = h
3835
3839
  added_w_space = 1 if slim else 7
@@ -3861,15 +3865,15 @@ class MainTable(tk.Canvas):
3861
3865
  if tw > w:
3862
3866
  w = tw
3863
3867
  if h < min_rh:
3864
- h = int(min_rh)
3865
- elif h > self.max_row_height:
3866
- h = int(self.max_row_height)
3868
+ h = min_rh
3869
+ elif h > max_row_height:
3870
+ h = max_row_height
3867
3871
  if h > rhs[datarn]:
3868
3872
  rhs[datarn] = h
3869
3873
  if w < min_column_width:
3870
- w = int(min_column_width)
3871
- elif w > self.max_column_width:
3872
- w = int(self.max_column_width)
3874
+ w = min_column_width
3875
+ elif w > max_column_width:
3876
+ w = max_column_width
3873
3877
  cws.append(w)
3874
3878
  self.set_row_positions(itr=rhs.values())
3875
3879
  self.set_col_positions(itr=cws)
@@ -5453,8 +5457,8 @@ class MainTable(tk.Canvas):
5453
5457
  resized_rows = False
5454
5458
  if self.PAR.ops.auto_resize_columns and self.allow_auto_resize_columns and col_pos_exists:
5455
5459
  max_w = can_width - self.PAR.ops.empty_horizontal
5456
- if self.PAR.ops.auto_resize_columns < self.min_column_width:
5457
- min_column_width = self.column_width
5460
+ if self.PAR.ops.auto_resize_columns < self.PAR.ops.min_column_width:
5461
+ min_column_width = self.PAR.ops.min_column_width
5458
5462
  else:
5459
5463
  min_column_width = self.PAR.ops.auto_resize_columns
5460
5464
  if (len(self.col_positions) - 1) * min_column_width < max_w:
@@ -5679,7 +5683,7 @@ class MainTable(tk.Canvas):
5679
5683
  color_tup(self.PAR.ops.table_selected_cells_fg),
5680
5684
  color_tup(self.PAR.ops.table_selected_columns_fg),
5681
5685
  color_tup(self.PAR.ops.table_selected_rows_fg),
5682
- )
5686
+ )
5683
5687
  else:
5684
5688
  override = tuple()
5685
5689
 
@@ -5934,7 +5938,7 @@ class MainTable(tk.Canvas):
5934
5938
  rows: bool = True,
5935
5939
  columns: bool = True,
5936
5940
  reverse: bool = False,
5937
- ) -> Generator[int]:
5941
+ ) -> tuple[tuple[int, SelectionBox]]:
5938
5942
  """
5939
5943
  Most recent selection box should be last
5940
5944
  """
@@ -6136,7 +6140,7 @@ class MainTable(tk.Canvas):
6136
6140
  self.itemconfig(item, state="hidden")
6137
6141
 
6138
6142
  def hide_selection_box(self, item: int | None) -> bool:
6139
- if item is None or item is True:
6143
+ if item is None or item is True or item not in self.selection_boxes:
6140
6144
  return
6141
6145
  box = self.selection_boxes.pop(item)
6142
6146
  self.hide_box(box.fill_iid)
@@ -6387,31 +6391,55 @@ class MainTable(tk.Canvas):
6387
6391
  def recreate_all_selection_boxes(self) -> None:
6388
6392
  if not self.selected:
6389
6393
  return
6394
+ modified = False
6390
6395
  for item, box in self.get_selection_items():
6391
6396
  r1, c1, r2, c2 = box.coords
6397
+ if not modified:
6398
+ modified = (
6399
+ r1 >= len(self.row_positions) - 1
6400
+ or c1 >= len(self.col_positions) - 1
6401
+ or r2 > len(self.row_positions) - 1
6402
+ or c2 > len(self.col_positions) - 1
6403
+ )
6392
6404
  if r1 >= len(self.row_positions) - 1:
6393
6405
  if len(self.row_positions) > 1:
6394
6406
  r1 = len(self.row_positions) - 2
6395
6407
  else:
6396
- r1 = len(self.row_positions) - 1
6408
+ r1 = 0
6397
6409
  if c1 >= len(self.col_positions) - 1:
6398
6410
  if len(self.col_positions) > 1:
6399
6411
  c1 = len(self.col_positions) - 2
6400
6412
  else:
6401
- c1 = len(self.col_positions) - 1
6413
+ c1 = 0
6402
6414
  if r2 > len(self.row_positions) - 1:
6403
6415
  r2 = len(self.row_positions) - 1
6404
6416
  if c2 > len(self.col_positions) - 1:
6405
6417
  c2 = len(self.col_positions) - 1
6406
- self.recreate_selection_box(r1, c1, r2, c2, item)
6418
+ self.recreate_selection_box(r1, c1, r2, c2, item, run_binding=False)
6419
+
6407
6420
  if self.selected:
6408
6421
  r = self.selected.row
6409
6422
  c = self.selected.column
6410
6423
  if r < len(self.row_positions) - 1 and c < len(self.col_positions) - 1:
6411
- self.set_currently_selected(r, c, item=self.selected.fill_iid)
6424
+ self.set_currently_selected(
6425
+ r,
6426
+ c,
6427
+ item=self.selected.fill_iid,
6428
+ run_binding=False,
6429
+ )
6412
6430
  else:
6413
6431
  box = self.selection_boxes[self.selected.fill_iid]
6414
- self.set_currently_selected(box.coords.from_r, box.coords.from_c, item=box.fill_iid)
6432
+ self.set_currently_selected(
6433
+ box.coords.from_r,
6434
+ box.coords.from_c,
6435
+ item=box.fill_iid,
6436
+ run_binding=False,
6437
+ )
6438
+ if modified:
6439
+ self.PAR.emit_event(
6440
+ "<<SheetSelect>>",
6441
+ data=self.get_select_event(self.being_drawn_item),
6442
+ )
6415
6443
 
6416
6444
  def get_redraw_selections(self, startr: int, endr: int, startc: int, endc: int) -> dict:
6417
6445
  d = defaultdict(set)
@@ -6710,7 +6738,6 @@ class MainTable(tk.Canvas):
6710
6738
  h = self.row_positions[r + 1] - y + 1
6711
6739
  if text is None:
6712
6740
  text = f"{self.get_cell_data(self.datarn(r), self.datacn(c), none_to_empty_str = True)}"
6713
- bg, fg = self.PAR.ops.table_bg, self.PAR.ops.table_fg
6714
6741
  kwargs = {
6715
6742
  "menu_kwargs": DotDict(
6716
6743
  {
@@ -6728,8 +6755,10 @@ class MainTable(tk.Canvas):
6728
6755
  "width": w,
6729
6756
  "height": h,
6730
6757
  "show_border": True,
6731
- "bg": bg,
6732
- "fg": fg,
6758
+ "bg": self.PAR.ops.table_editor_bg,
6759
+ "fg": self.PAR.ops.table_editor_fg,
6760
+ "select_bg": self.PAR.ops.table_editor_select_bg,
6761
+ "select_fg": self.PAR.ops.table_editor_select_fg,
6733
6762
  "align": self.get_cell_align(r, c),
6734
6763
  "r": r,
6735
6764
  "c": c,
@@ -6868,7 +6897,7 @@ class MainTable(tk.Canvas):
6868
6897
  name="end_edit_table",
6869
6898
  sheet=self.PAR.name,
6870
6899
  widget=self,
6871
- cells_table={(datarn, datacn): text_editor_value},
6900
+ cells_table={(datarn, datacn): self.get_cell_data(datarn, datacn)},
6872
6901
  key=event.keysym,
6873
6902
  value=text_editor_value,
6874
6903
  loc=Loc(r, c),
@@ -7062,22 +7091,15 @@ class MainTable(tk.Canvas):
7062
7091
  selected=self.selected,
7063
7092
  )
7064
7093
  try_binding(self.dropdown.window.modified_function, event_data)
7065
- val = self.dropdown.window.search_and_see(event_data)
7066
7094
  # return to tk.Text action if control/command is held down
7067
7095
  # or keysym was not a character
7068
7096
  if (hasattr(event, "state") and event.state & (0x0004 | 0x00000010)) or (
7069
- hasattr(event, "keysym") and len(event.keysym) > 2
7097
+ hasattr(event, "keysym") and len(event.keysym) > 2 and event.keysym != "space"
7070
7098
  ):
7071
7099
  return
7072
- self.text_editor.tktext.unbind("<KeyRelease>")
7073
- self.text_editor.autocomplete(val)
7074
- self.text_editor.tktext.bind(
7075
- "<KeyRelease>",
7076
- self.dropdown_text_editor_modified,
7077
- )
7100
+ self.text_editor.autocomplete(self.dropdown.window.search_and_see(event_data))
7078
7101
  return "break"
7079
7102
 
7080
- # c is displayed col
7081
7103
  def open_dropdown_window(
7082
7104
  self,
7083
7105
  r: int,
@@ -7105,6 +7127,10 @@ class MainTable(tk.Canvas):
7105
7127
  reset_kwargs = {
7106
7128
  "r": r,
7107
7129
  "c": c,
7130
+ "bg": self.PAR.ops.table_editor_bg,
7131
+ "fg": self.PAR.ops.table_editor_fg,
7132
+ "select_bg": self.PAR.ops.table_editor_select_bg,
7133
+ "select_fg": self.PAR.ops.table_editor_select_fg,
7108
7134
  "width": win_w,
7109
7135
  "height": win_h,
7110
7136
  "font": self.PAR.ops.table_font,
@@ -7133,12 +7159,12 @@ class MainTable(tk.Canvas):
7133
7159
  window=self.dropdown.window,
7134
7160
  anchor=anchor,
7135
7161
  )
7162
+ self.update_idletasks()
7136
7163
  if kwargs["state"] == "normal":
7137
7164
  self.text_editor.tktext.bind(
7138
7165
  "<KeyRelease>",
7139
7166
  self.dropdown_text_editor_modified,
7140
7167
  )
7141
- self.update_idletasks()
7142
7168
  try:
7143
7169
  self.after(1, lambda: self.text_editor.tktext.focus())
7144
7170
  self.after(2, self.text_editor.window.scroll_to_bottom())
@@ -7146,7 +7172,6 @@ class MainTable(tk.Canvas):
7146
7172
  return
7147
7173
  redraw = False
7148
7174
  else:
7149
- self.update_idletasks()
7150
7175
  self.dropdown.window.bind("<FocusOut>", lambda _: self.close_dropdown_window(r, c))
7151
7176
  self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
7152
7177
  self.dropdown.window.focus_set()
tksheet/other_classes.py CHANGED
@@ -5,6 +5,7 @@ from collections import namedtuple
5
5
  from collections.abc import Callable, Generator, Hashable, Iterator
6
6
  from functools import partial
7
7
  from typing import Literal
8
+ import tkinter as tk
8
9
 
9
10
  pickle_obj = partial(pickle.dumps, protocol=pickle.HIGHEST_PROTOCOL)
10
11
 
@@ -18,7 +19,7 @@ Box_t = namedtuple(
18
19
  "from_r from_c upto_r upto_c type_",
19
20
  )
20
21
  Box_st = namedtuple("Box_st", "coords type_")
21
- Loc = namedtuple("Loc", "row column")
22
+ Loc = namedtuple("Loc", "row column", defaults=(None, None))
22
23
 
23
24
  Highlight = namedtuple(
24
25
  "Highlight",
@@ -489,25 +490,25 @@ class TextEditorStorage:
489
490
  if self.window:
490
491
  return self.window.get()
491
492
  return ""
492
-
493
+
493
494
  def set(self, value: str) -> None:
494
495
  if not self.window:
495
496
  return
496
497
  self.window.set_text(value)
497
-
498
- def highlight_from(self, r: int | str, c: int | str) -> None:
499
- index = self.window.tktext.index(f"{r}.{c}")
500
- self.window.tktext.tag_add('sel', index, 'end')
501
- self.window.tktext.mark_set('insert', f"{r}.{c}")
502
-
498
+
499
+ def highlight_from(self, index: tk.Misc, r: int | str, c: int | str) -> None:
500
+ self.window.tktext.tag_add("sel", index, "end")
501
+ self.window.tktext.mark_set("insert", f"{r}.{c}")
502
+
503
503
  def autocomplete(self, value: str | None) -> None:
504
504
  current_val = self.get()
505
- if not value or len(current_val) >= len(value) or current_val != value[:len(current_val)]:
505
+ if not value or len(current_val) >= len(value) or current_val != value[: len(current_val)]:
506
506
  return
507
- cursor_pos = self.tktext.index('insert')
508
- line, column = cursor_pos.split('.')
509
- self.window.set_text(value)
510
- self.highlight_from(line, column)
507
+ cursor_pos = self.tktext.index("insert")
508
+ line, column = cursor_pos.split(".")
509
+ index = self.window.tktext.index(f"{line}.{column}")
510
+ self.tktext.insert(index, value[len(current_val) :])
511
+ self.highlight_from(index, line, column)
511
512
 
512
513
  @property
513
514
  def tktext(self) -> object: