tksheet 7.3.2__py3-none-any.whl → 7.3.4__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
@@ -3,42 +3,17 @@ from __future__ import annotations
3
3
  import csv as csv
4
4
  import io
5
5
  import tkinter as tk
6
- from bisect import (
7
- bisect_left,
8
- bisect_right,
9
- )
10
- from collections import (
11
- defaultdict,
12
- deque,
13
- )
14
- from collections.abc import (
15
- Callable,
16
- Generator,
17
- Hashable,
18
- Sequence,
19
- )
20
- from functools import (
21
- partial,
22
- )
23
- from itertools import (
24
- accumulate,
25
- chain,
26
- cycle,
27
- filterfalse,
28
- islice,
29
- repeat,
30
- )
31
- from math import (
32
- ceil,
33
- floor,
34
- )
6
+ from bisect import bisect_left, bisect_right
7
+ from collections import defaultdict, deque
8
+ from collections.abc import Callable, Generator, Hashable, Sequence
9
+ from functools import partial
10
+ from itertools import accumulate, chain, cycle, filterfalse, islice, repeat
11
+ from math import ceil, floor
35
12
  from operator import itemgetter
36
13
  from tkinter import TclError
37
14
  from typing import Literal
38
15
 
39
- from .colors import (
40
- color_map,
41
- )
16
+ from .colors import color_map
42
17
  from .constants import (
43
18
  USER_OS,
44
19
  bind_add_columns,
@@ -52,9 +27,7 @@ from .constants import (
52
27
  text_editor_to_unbind,
53
28
  val_modifying_options,
54
29
  )
55
- from .find_window import (
56
- FindWindow,
57
- )
30
+ from .find_window import FindWindow
58
31
  from .formatters import (
59
32
  data_to_str,
60
33
  format_data,
@@ -67,6 +40,7 @@ from .functions import (
67
40
  add_to_displayed,
68
41
  b_index,
69
42
  bisect_in,
43
+ box_gen_coords,
70
44
  box_is_single_cell,
71
45
  cell_right_within_box,
72
46
  color_tup,
@@ -78,6 +52,7 @@ from .functions import (
78
52
  event_has_char_key,
79
53
  event_opens_dropdown_or_checkbox,
80
54
  float_to_int,
55
+ gen_coords,
81
56
  gen_formatted,
82
57
  get_data_from_clipboard,
83
58
  get_new_indexes,
@@ -86,6 +61,7 @@ from .functions import (
86
61
  insert_items,
87
62
  int_x_iter,
88
63
  is_iterable,
64
+ is_last_cell,
89
65
  is_type_int,
90
66
  len_to_idx,
91
67
  mod_event_val,
@@ -93,6 +69,7 @@ from .functions import (
93
69
  mod_span_widget,
94
70
  move_elements_by_mapping,
95
71
  new_tk_event,
72
+ next_cell,
96
73
  rounded_box_coords,
97
74
  span_idxs_post_move,
98
75
  stored_event_dict,
@@ -115,12 +92,8 @@ from .other_classes import (
115
92
  SelectionBox,
116
93
  TextEditorStorage,
117
94
  )
118
- from .text_editor import (
119
- TextEditor,
120
- )
121
- from .types import (
122
- AnyIter,
123
- )
95
+ from .text_editor import TextEditor
96
+ from .types import AnyIter
124
97
 
125
98
 
126
99
  class MainTable(tk.Canvas):
@@ -358,10 +331,8 @@ class MainTable(tk.Canvas):
358
331
  reset_col_positions=False,
359
332
  deselect_all=False,
360
333
  )
334
+ self.rc_popup_menu, self.empty_rc_popup_menu = None, None
361
335
  self.reset_col_positions()
362
-
363
- self.rc_popup_menu = None
364
- self.empty_rc_popup_menu = None
365
336
  self.basic_bindings()
366
337
  self.create_rc_menus()
367
338
 
@@ -547,19 +518,25 @@ class MainTable(tk.Canvas):
547
518
  self.find_window.tktext.focus_set()
548
519
  return "break"
549
520
 
550
- def find_see_and_set(self, coords: tuple[int, int] | None, just_see: bool = False) -> tuple[int, int]:
521
+ def find_see_and_set(
522
+ self,
523
+ coords: tuple[int, int, int | None] | None,
524
+ just_see: bool = False,
525
+ ) -> tuple[int, int]:
551
526
  if coords:
527
+ row, column, item = coords
552
528
  if not self.all_rows_displayed:
553
- coords = (self.disprn(coords[0]), coords[1])
529
+ row = self.disprn(row)
554
530
  if not self.all_columns_displayed:
555
- coords = (coords[0], self.dispcn(coords[1]))
531
+ column = self.dispcn(column)
556
532
  if not just_see:
557
533
  if self.find_window.window.find_in_selection:
558
- self.set_currently_selected(*coords)
534
+ self.set_currently_selected(row, column, item=item)
559
535
  else:
560
- self.select_cell(*coords, redraw=False)
536
+ self.select_cell(row, column, redraw=False)
561
537
  if not self.see(
562
- *coords,
538
+ row,
539
+ column,
563
540
  keep_yscroll=False,
564
541
  keep_xscroll=False,
565
542
  bottom_right_corner=False,
@@ -569,78 +546,6 @@ class MainTable(tk.Canvas):
569
546
  self.refresh()
570
547
  return coords
571
548
 
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
549
  def find_match(self, find: str, r: int, c: int) -> bool:
645
550
  return (
646
551
  not find
@@ -653,41 +558,106 @@ class MainTable(tk.Canvas):
653
558
  )
654
559
  )
655
560
 
656
- def find_within_sels(
561
+ def find_within_match(self, find: str, r: int, c: int) -> bool:
562
+ if not self.all_rows_displayed:
563
+ r = self.datarn(r)
564
+ if not self.all_columns_displayed:
565
+ c = self.datacn(c)
566
+ return self.find_match(find, r, c)
567
+
568
+ def find_within_current_box(
657
569
  self,
570
+ current_box: SelectionBox,
658
571
  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,
572
+ reverse: bool,
573
+ ) -> None | tuple[int, int]:
574
+ start_row, start_col = next_cell(
575
+ *current_box.coords,
576
+ self.selected.row,
577
+ self.selected.column,
578
+ reverse=reverse,
666
579
  )
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)
580
+ _, _, r2, c2 = current_box.coords
581
+ for r, c in box_gen_coords(start_row, start_col, c2, r2, reverse=reverse):
582
+ if self.find_within_match(find, r, c):
583
+ return (r, c, current_box.fill_iid)
584
+ return None
585
+
586
+ def find_within_non_current_boxes(
587
+ self,
588
+ current_id: int,
589
+ find: str,
590
+ reverse: bool,
591
+ ) -> None | tuple[int, int]:
592
+ if reverse:
593
+ # iterate backwards through selection boxes from the box before current
594
+ idx = next(i for i, k in enumerate(reversed(self.selection_boxes)) if k == current_id)
595
+ for item, box in chain(
596
+ islice(reversed(self.selection_boxes.items()), idx + 1, None),
597
+ islice(reversed(self.selection_boxes.items()), 0, idx),
598
+ ):
599
+ for r, c in gen_coords(*box.coords, reverse=reverse):
600
+ if self.find_within_match(find, r, c):
601
+ return (r, c, item)
602
+ else:
603
+ # iterate forwards through selection boxes from the box after current
604
+ idx = next(i for i, k in enumerate(self.selection_boxes) if k == current_id)
605
+ for item, box in chain(
606
+ islice(self.selection_boxes.items(), idx + 1, None),
607
+ islice(self.selection_boxes.items(), 0, idx),
608
+ ):
609
+ for r, c in gen_coords(*box.coords, reverse=reverse):
610
+ if self.find_within_match(find, r, c):
611
+ return (r, c, item)
612
+ return None
613
+
614
+ def find_within(
615
+ self,
616
+ find: str,
617
+ reverse: bool = False,
618
+ ) -> tuple[int, int, int] | None:
619
+ if not self.selected:
620
+ return None
621
+ current_box = self.selection_boxes[self.selected.fill_iid]
622
+ current_id = self.selected.fill_iid
623
+ if is_last_cell(*current_box.coords, self.selected.row, self.selected.column, reverse=reverse):
624
+ if coord := self.find_within_non_current_boxes(current_id=current_id, find=find, reverse=reverse):
625
+ return coord
626
+ if coord := self.find_within_current_box(current_box=current_box, find=find, reverse=reverse):
627
+ return coord
628
+ else:
629
+ if coord := self.find_within_current_box(current_box=current_box, find=find, reverse=reverse):
630
+ return coord
631
+ if coord := self.find_within_non_current_boxes(current_id=current_id, find=find, reverse=reverse):
632
+ return coord
675
633
  return None
676
634
 
677
635
  def find_all_cells(
678
636
  self,
679
637
  find: str,
680
638
  reverse: bool = False,
681
- ) -> tuple[int, int] | None:
682
- row, col, _ = self.find_get_start_coords(plus_one=True, reverse=reverse)
639
+ ) -> tuple[int, int, None] | None:
640
+ if self.selected:
641
+ row, col = next_cell(
642
+ 0,
643
+ 0,
644
+ len(self.row_positions) - 1,
645
+ len(self.col_positions) - 1,
646
+ self.selected.row,
647
+ self.selected.column,
648
+ reverse=reverse,
649
+ )
650
+ else:
651
+ row, col = 0, 0
683
652
  row, col = self.datarn(row), self.datacn(col)
684
- return next(
653
+ result = next(
685
654
  (
686
655
  (r, c)
687
- for r, c in self.find_gen_all_cells(
656
+ for r, c in box_gen_coords(
688
657
  start_row=row,
689
658
  start_col=col,
690
659
  total_cols=self.total_data_cols(include_header=False),
660
+ total_rows=self.total_data_rows(include_index=False),
691
661
  reverse=reverse,
692
662
  )
693
663
  if (
@@ -698,13 +668,16 @@ class MainTable(tk.Canvas):
698
668
  ),
699
669
  None,
700
670
  )
671
+ if result:
672
+ return result + (None,)
673
+ return None
701
674
 
702
675
  def find_next(self, event: tk.Misc | None = None) -> Literal["break"]:
703
676
  find = self.find_window.get().lower()
704
677
  if not self.find_window.open:
705
678
  self.open_find_window(focus=False)
706
679
  if self.find_window.window.find_in_selection:
707
- self.find_see_and_set(self.find_within_sels(find))
680
+ self.find_see_and_set(self.find_within(find))
708
681
  else:
709
682
  self.find_see_and_set(self.find_all_cells(find))
710
683
  return "break"
@@ -714,7 +687,7 @@ class MainTable(tk.Canvas):
714
687
  if not self.find_window.open:
715
688
  self.open_find_window(focus=False)
716
689
  if self.find_window.window.find_in_selection:
717
- self.find_see_and_set(self.find_within_sels(find, reverse=True))
690
+ self.find_see_and_set(self.find_within(find, reverse=True))
718
691
  else:
719
692
  self.find_see_and_set(self.find_all_cells(find, reverse=True))
720
693
  return "break"
@@ -1216,25 +1189,24 @@ class MainTable(tk.Canvas):
1216
1189
  event_data["selection_boxes"] = boxes
1217
1190
  if not try_binding(self.extra_begin_delete_key_func, event_data, "begin_delete"):
1218
1191
  return
1219
- for r1, c1, r2, c2 in boxes:
1220
- for r in range(r1, r2):
1221
- for c in range(c1, c2):
1222
- datarn, datacn = self.datarn(r), self.datacn(c)
1223
- val = self.get_value_for_empty_cell(datarn, datacn)
1224
- if (
1225
- not self.edit_validation_func
1226
- or not validation
1227
- or (
1228
- self.edit_validation_func
1229
- and (val := self.edit_validation_func(mod_event_val(event_data, val, (r, c)))) is not None
1230
- )
1231
- ):
1232
- event_data = self.event_data_set_cell(
1233
- datarn,
1234
- datacn,
1235
- val,
1236
- event_data,
1237
- )
1192
+ for box in boxes:
1193
+ for r, c in gen_coords(*box):
1194
+ datarn, datacn = self.datarn(r), self.datacn(c)
1195
+ val = self.get_value_for_empty_cell(datarn, datacn)
1196
+ if (
1197
+ not self.edit_validation_func
1198
+ or not validation
1199
+ or (
1200
+ self.edit_validation_func
1201
+ and (val := self.edit_validation_func(mod_event_val(event_data, val, (r, c)))) is not None
1202
+ )
1203
+ ):
1204
+ event_data = self.event_data_set_cell(
1205
+ datarn,
1206
+ datacn,
1207
+ val,
1208
+ event_data,
1209
+ )
1238
1210
  if event_data["cells"]["table"]:
1239
1211
  self.refresh()
1240
1212
  self.undo_stack.append(stored_event_dict(event_data))
@@ -2011,9 +1983,9 @@ class MainTable(tk.Canvas):
2011
1983
  need_redraw = True
2012
1984
  else:
2013
1985
  if r is not None and not keep_yscroll:
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
1986
+ y = max(
1987
+ 0, int(self.row_positions[r] + ((self.row_positions[r + 1] - self.row_positions[r]) * r_pc)) - 2
1988
+ )
2017
1989
  y = y / (self.row_positions[-1] + self.PAR.ops.empty_vertical)
2018
1990
  args = [
2019
1991
  "moveto",
@@ -2038,9 +2010,9 @@ class MainTable(tk.Canvas):
2038
2010
  need_redraw = True
2039
2011
  else:
2040
2012
  if c is not None and not keep_xscroll:
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
2013
+ x = max(
2014
+ 0, int(self.col_positions[c] + ((self.col_positions[c + 1] - self.col_positions[c]) * c_pc)) - 2
2015
+ )
2044
2016
  x = x / (self.col_positions[-1] + self.PAR.ops.empty_horizontal)
2045
2017
  args = [
2046
2018
  "moveto",
@@ -2391,15 +2363,11 @@ class MainTable(tk.Canvas):
2391
2363
  def page_UP(self, event: object = None) -> None:
2392
2364
  height = self.winfo_height()
2393
2365
  top = self.canvasy(0)
2394
- scrollto_y = top - height
2395
- if scrollto_y < 0:
2396
- scrollto_y = 0
2366
+ scrollto_y = max(0, top - height)
2397
2367
  if self.PAR.ops.page_up_down_select_row:
2398
2368
  r = bisect_left(self.row_positions, scrollto_y)
2399
2369
  if self.selected and self.selected.row == r:
2400
- r -= 1
2401
- if r < 0:
2402
- r = 0
2370
+ r = max(0, r - 1)
2403
2371
  if self.RI.row_selection_enabled and (
2404
2372
  self.anything_selected(exclude_columns=True, exclude_cells=True) or not self.anything_selected()
2405
2373
  ):
@@ -5492,7 +5460,7 @@ class MainTable(tk.Canvas):
5492
5460
  can_width: int | None,
5493
5461
  dont_blend: bool,
5494
5462
  alternate_color: Highlight | None,
5495
- ) -> str:
5463
+ ) -> tuple[str, bool]:
5496
5464
  redrawn = False
5497
5465
  if (datarn, datacn) in self.progress_bars:
5498
5466
  kwargs = self.progress_bars[(datarn, datacn)]
@@ -5571,7 +5539,6 @@ class MainTable(tk.Canvas):
5571
5539
  if self.get_cell_kwargs(datarn, datacn, key="dropdown") and self.PAR.ops.show_dropdown_borders
5572
5540
  else ""
5573
5541
  ),
5574
- tag="hi",
5575
5542
  )
5576
5543
  if isinstance(kwargs, ProgressBar):
5577
5544
  if kwargs.del_when_done and kwargs.percent >= 100:
@@ -5597,7 +5564,17 @@ class MainTable(tk.Canvas):
5597
5564
  txtfg = self.PAR.ops.table_fg
5598
5565
  return txtfg, redrawn
5599
5566
 
5600
- def redraw_highlight(self, x1, y1, x2, y2, fill, outline, tag, can_width=None, pc=None):
5567
+ def redraw_highlight(
5568
+ self,
5569
+ x1: int | float,
5570
+ y1: int | float,
5571
+ x2: int | float,
5572
+ y2: int | float,
5573
+ fill: str,
5574
+ outline: str,
5575
+ can_width: None | float = None,
5576
+ pc: None | float = None,
5577
+ ) -> bool:
5601
5578
  if not is_type_int(pc) or pc >= 100:
5602
5579
  coords = (
5603
5580
  x1 - 1 if outline else x1,
@@ -5615,66 +5592,61 @@ class MainTable(tk.Canvas):
5615
5592
  if showing:
5616
5593
  self.itemconfig(iid, fill=fill, outline=outline)
5617
5594
  else:
5618
- self.itemconfig(iid, fill=fill, outline=outline, tag=tag, state="normal")
5595
+ self.itemconfig(iid, fill=fill, outline=outline, state="normal")
5596
+ self.tag_raise(iid)
5619
5597
  else:
5620
- iid = self.create_rectangle(coords, fill=fill, outline=outline, tag=tag)
5598
+ iid = self.create_rectangle(coords, fill=fill, outline=outline)
5621
5599
  self.disp_high[iid] = True
5622
5600
  return True
5623
5601
 
5624
- def redraw_gridline(
5625
- self,
5626
- points,
5627
- fill,
5628
- width,
5629
- tag,
5630
- ):
5631
- if self.hidd_grid:
5632
- iid, sh = self.hidd_grid.popitem()
5633
- self.coords(iid, points)
5634
- if sh:
5635
- self.itemconfig(
5636
- iid,
5637
- fill=fill,
5638
- width=width,
5639
- capstyle=tk.BUTT,
5640
- joinstyle=tk.ROUND,
5641
- )
5602
+ def redraw_gridline(self, points: list[float]) -> None:
5603
+ if points:
5604
+ if self.hidd_grid:
5605
+ iid, sh = self.hidd_grid.popitem()
5606
+ self.coords(iid, points)
5607
+ if sh:
5608
+ self.itemconfig(
5609
+ iid,
5610
+ fill=self.PAR.ops.table_grid_fg,
5611
+ width=1,
5612
+ capstyle=tk.BUTT,
5613
+ joinstyle=tk.ROUND,
5614
+ )
5615
+ else:
5616
+ self.itemconfig(
5617
+ iid,
5618
+ fill=self.PAR.ops.table_grid_fg,
5619
+ width=1,
5620
+ capstyle=tk.BUTT,
5621
+ joinstyle=tk.ROUND,
5622
+ state="normal",
5623
+ )
5624
+ self.tag_raise(iid)
5642
5625
  else:
5643
- self.itemconfig(
5644
- iid,
5645
- fill=fill,
5646
- width=width,
5626
+ iid = self.create_line(
5627
+ points,
5628
+ fill=self.PAR.ops.table_grid_fg,
5629
+ width=1,
5647
5630
  capstyle=tk.BUTT,
5648
5631
  joinstyle=tk.ROUND,
5649
- state="normal",
5632
+ tag="g",
5650
5633
  )
5651
- else:
5652
- iid = self.create_line(
5653
- points,
5654
- fill=fill,
5655
- width=width,
5656
- capstyle=tk.BUTT,
5657
- joinstyle=tk.ROUND,
5658
- tag=tag,
5659
- )
5660
- self.disp_grid[iid] = True
5661
- return iid
5634
+ self.disp_grid[iid] = True
5662
5635
 
5663
5636
  def redraw_dropdown(
5664
5637
  self,
5665
- x1,
5666
- y1,
5667
- x2,
5668
- y2,
5669
- fill,
5670
- outline,
5671
- tag,
5672
- draw_outline=True,
5673
- draw_arrow=True,
5674
- open_=False,
5675
- ):
5638
+ x1: int | float,
5639
+ y1: int | float,
5640
+ x2: int | float,
5641
+ y2: int | float,
5642
+ fill: str,
5643
+ outline: str,
5644
+ draw_outline: bool = True,
5645
+ draw_arrow: bool = True,
5646
+ open_: bool = False,
5647
+ ) -> None:
5676
5648
  if draw_outline and self.PAR.ops.show_dropdown_borders:
5677
- self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.PAR.ops.table_fg, tag=tag)
5649
+ self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.PAR.ops.table_fg)
5678
5650
  if draw_arrow:
5679
5651
  mod = (self.table_txt_height - 1) if self.table_txt_height % 2 else self.table_txt_height
5680
5652
  small_mod = int(mod / 5)
@@ -5705,13 +5677,12 @@ class MainTable(tk.Canvas):
5705
5677
  if sh:
5706
5678
  self.itemconfig(t, fill=fill)
5707
5679
  else:
5708
- self.itemconfig(t, fill=fill, tag=tag, state="normal")
5680
+ self.itemconfig(t, fill=fill, state="normal")
5709
5681
  self.lift(t)
5710
5682
  else:
5711
5683
  t = self.create_line(
5712
5684
  points,
5713
5685
  fill=fill,
5714
- tag=tag,
5715
5686
  width=2,
5716
5687
  capstyle=tk.ROUND,
5717
5688
  joinstyle=tk.BEVEL,
@@ -5726,7 +5697,6 @@ class MainTable(tk.Canvas):
5726
5697
  y2: int | float,
5727
5698
  fill: str,
5728
5699
  outline: str,
5729
- tag: str | tuple,
5730
5700
  draw_check: bool = False,
5731
5701
  ) -> None:
5732
5702
  points = rounded_box_coords(x1, y1, x2, y2)
@@ -5736,10 +5706,10 @@ class MainTable(tk.Canvas):
5736
5706
  if sh:
5737
5707
  self.itemconfig(t, fill=outline, outline=fill)
5738
5708
  else:
5739
- self.itemconfig(t, fill=outline, outline=fill, tag=tag, state="normal")
5709
+ self.itemconfig(t, fill=outline, outline=fill, state="normal")
5740
5710
  self.lift(t)
5741
5711
  else:
5742
- t = self.create_polygon(points, fill=outline, outline=fill, tag=tag, smooth=True)
5712
+ t = self.create_polygon(points, fill=outline, outline=fill, smooth=True)
5743
5713
  self.disp_checkbox[t] = True
5744
5714
  if draw_check:
5745
5715
  x1 = x1 + 4
@@ -5753,28 +5723,13 @@ class MainTable(tk.Canvas):
5753
5723
  if sh:
5754
5724
  self.itemconfig(t, fill=fill, outline=outline)
5755
5725
  else:
5756
- self.itemconfig(t, fill=fill, outline=outline, tag=tag, state="normal")
5726
+ self.itemconfig(t, fill=fill, outline=outline, state="normal")
5757
5727
  self.lift(t)
5758
5728
  else:
5759
- t = self.create_polygon(points, fill=fill, outline=outline, tag=tag, smooth=True)
5729
+ t = self.create_polygon(points, fill=fill, outline=outline, smooth=True)
5760
5730
  self.disp_checkbox[t] = True
5761
5731
 
5762
- def main_table_redraw_grid_and_text(
5763
- self,
5764
- redraw_header: bool = False,
5765
- redraw_row_index: bool = False,
5766
- redraw_table: bool = True,
5767
- setting_views: bool = False,
5768
- ) -> bool:
5769
- try:
5770
- can_width = self.winfo_width()
5771
- can_height = self.winfo_height()
5772
- except Exception:
5773
- return False
5774
- row_pos_exists = self.row_positions != [0] and self.row_positions
5775
- col_pos_exists = self.col_positions != [0] and self.col_positions
5776
- resized_cols = False
5777
- resized_rows = False
5732
+ def _auto_resize_columns(self, can_width: float, col_pos_exists: bool) -> bool:
5778
5733
  if self.PAR.ops.auto_resize_columns and self.allow_auto_resize_columns and col_pos_exists:
5779
5734
  max_w = can_width - self.PAR.ops.empty_horizontal
5780
5735
  if self.PAR.ops.auto_resize_columns < self.PAR.ops.min_column_width:
@@ -5782,7 +5737,6 @@ class MainTable(tk.Canvas):
5782
5737
  else:
5783
5738
  min_column_width = self.PAR.ops.auto_resize_columns
5784
5739
  if (len(self.col_positions) - 1) * min_column_width < max_w:
5785
- resized_cols = True
5786
5740
  change = int((max_w - self.col_positions[-1]) / (len(self.col_positions) - 1))
5787
5741
  widths = [
5788
5742
  int(b - a) + change - 1
@@ -5799,6 +5753,10 @@ class MainTable(tk.Canvas):
5799
5753
  if i not in diffs:
5800
5754
  widths[i] -= change
5801
5755
  self.col_positions = list(accumulate(chain([0], widths)))
5756
+ return True
5757
+ return False
5758
+
5759
+ def _auto_resize_rows(self, can_height: float, row_pos_exists: bool) -> bool:
5802
5760
  if self.PAR.ops.auto_resize_rows and self.allow_auto_resize_rows and row_pos_exists:
5803
5761
  max_h = can_height - self.PAR.ops.empty_vertical
5804
5762
  if self.PAR.ops.auto_resize_rows < self.min_row_height:
@@ -5806,7 +5764,6 @@ class MainTable(tk.Canvas):
5806
5764
  else:
5807
5765
  min_row_height = self.PAR.ops.auto_resize_rows
5808
5766
  if (len(self.row_positions) - 1) * min_row_height < max_h:
5809
- resized_rows = True
5810
5767
  change = int((max_h - self.row_positions[-1]) / (len(self.row_positions) - 1))
5811
5768
  heights = [
5812
5769
  int(b - a) + change - 1
@@ -5823,6 +5780,10 @@ class MainTable(tk.Canvas):
5823
5780
  if i not in diffs:
5824
5781
  heights[i] -= change
5825
5782
  self.row_positions = list(accumulate(chain([0], heights)))
5783
+ return True
5784
+ return False
5785
+
5786
+ def _manage_scroll_bars(self, can_height: float, can_width: float) -> None:
5826
5787
  if (
5827
5788
  self.PAR.ops.auto_resize_row_index is not True
5828
5789
  and can_width >= self.col_positions[-1] + self.PAR.ops.empty_horizontal
@@ -5849,6 +5810,26 @@ class MainTable(tk.Canvas):
5849
5810
  ):
5850
5811
  self.PAR.yscroll.grid(row=0, column=2, rowspan=3, sticky="nswe")
5851
5812
  self.PAR.yscroll_showing = True
5813
+
5814
+ def main_table_redraw_grid_and_text(
5815
+ self,
5816
+ redraw_header: bool = False,
5817
+ redraw_row_index: bool = False,
5818
+ redraw_table: bool = True,
5819
+ setting_views: bool = False,
5820
+ ) -> bool:
5821
+ try:
5822
+ can_width = self.winfo_width()
5823
+ can_height = self.winfo_height()
5824
+ except Exception:
5825
+ return False
5826
+ row_pos_exists = self.row_positions != [0] and self.row_positions
5827
+ col_pos_exists = self.col_positions != [0] and self.col_positions
5828
+
5829
+ resized_cols = self._auto_resize_columns(can_width=can_width, col_pos_exists=col_pos_exists)
5830
+ resized_rows = self._auto_resize_rows(can_height=can_height, row_pos_exists=row_pos_exists)
5831
+ self._manage_scroll_bars(can_height=can_height, can_width=can_width)
5832
+
5852
5833
  last_col_line_pos = self.col_positions[-1] + 1
5853
5834
  last_row_line_pos = self.row_positions[-1] + 1
5854
5835
  scrollregion = (
@@ -5864,6 +5845,7 @@ class MainTable(tk.Canvas):
5864
5845
  self.RI.configure_scrollregion(last_row_line_pos)
5865
5846
  if setting_views:
5866
5847
  return False
5848
+
5867
5849
  scrollpos_top = self.canvasy(0)
5868
5850
  scrollpos_bot = self.canvasy(can_height)
5869
5851
  scrollpos_left = self.canvasx(0)
@@ -5891,6 +5873,7 @@ class MainTable(tk.Canvas):
5891
5873
  for widget in (self, self.RI, self.CH, self.TL):
5892
5874
  widget.update_idletasks()
5893
5875
  return False
5876
+
5894
5877
  if self.find_window.open:
5895
5878
  w, h, x, y = self.get_find_window_dimensions_coords(w_width=self.winfo_width())
5896
5879
  self.coords(self.find_window.canvas_id, x, y)
@@ -5910,79 +5893,11 @@ class MainTable(tk.Canvas):
5910
5893
  self.disp_dropdown = {}
5911
5894
  self.hidd_checkbox.update(self.disp_checkbox)
5912
5895
  self.disp_checkbox = {}
5913
- if last_col_line_pos > scrollpos_right:
5914
- x_stop = scrollpos_right
5915
- else:
5916
- x_stop = last_col_line_pos
5917
- if last_row_line_pos > scrollpos_bot:
5918
- y_stop = scrollpos_bot
5919
- else:
5920
- y_stop = last_row_line_pos
5921
- if redraw_table and self.PAR.ops.show_horizontal_grid and row_pos_exists:
5922
- if self.PAR.ops.horizontal_grid_to_end_of_window:
5923
- x_grid_stop = scrollpos_right + can_width
5924
- else:
5925
- if last_col_line_pos > scrollpos_right:
5926
- x_grid_stop = x_stop + 1
5927
- else:
5928
- x_grid_stop = x_stop - 1
5929
- points = list(
5930
- chain.from_iterable(
5931
- [
5932
- (
5933
- scrollpos_left - 1,
5934
- self.row_positions[r],
5935
- x_grid_stop,
5936
- self.row_positions[r],
5937
- scrollpos_left - 1,
5938
- self.row_positions[r],
5939
- scrollpos_left - 1,
5940
- self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
5941
- )
5942
- for r in range(grid_start_row, grid_end_row)
5943
- ]
5944
- )
5945
- )
5946
- if points:
5947
- self.redraw_gridline(
5948
- points=points,
5949
- fill=self.PAR.ops.table_grid_fg,
5950
- width=1,
5951
- tag="g",
5952
- )
5953
- if redraw_table and self.PAR.ops.show_vertical_grid and col_pos_exists:
5954
- if self.PAR.ops.vertical_grid_to_end_of_window:
5955
- y_grid_stop = scrollpos_bot + can_height
5956
- else:
5957
- if last_row_line_pos > scrollpos_bot:
5958
- y_grid_stop = y_stop + 1
5959
- else:
5960
- y_grid_stop = y_stop - 1
5961
- points = list(
5962
- chain.from_iterable(
5963
- [
5964
- (
5965
- self.col_positions[c],
5966
- scrollpos_top - 1,
5967
- self.col_positions[c],
5968
- y_grid_stop,
5969
- self.col_positions[c],
5970
- scrollpos_top - 1,
5971
- self.col_positions[c + 1] if len(self.col_positions) - 1 > c else self.col_positions[c],
5972
- scrollpos_top - 1,
5973
- )
5974
- for c in range(grid_start_col, grid_end_col)
5975
- ]
5976
- )
5977
- )
5978
- if points:
5979
- self.redraw_gridline(
5980
- points=points,
5981
- fill=self.PAR.ops.table_grid_fg,
5982
- width=1,
5983
- tag="g",
5984
- )
5896
+ x_stop = min(last_col_line_pos, scrollpos_right)
5897
+ y_stop = min(last_row_line_pos, scrollpos_bot)
5985
5898
  if redraw_table:
5899
+ font = self.PAR.ops.table_font
5900
+ dd_coords = self.dropdown.get_coords()
5986
5901
  selections = self.get_redraw_selections(text_start_row, grid_end_row, text_start_col, grid_end_col)
5987
5902
  sel_cells_bg = color_tup(self.PAR.ops.table_selected_cells_bg)
5988
5903
  sel_cols_bg = color_tup(self.PAR.ops.table_selected_columns_bg)
@@ -6004,7 +5919,6 @@ class MainTable(tk.Canvas):
6004
5919
  else:
6005
5920
  alternate_color = None
6006
5921
  dont_blend = tuple()
6007
-
6008
5922
  if not self.PAR.ops.show_selected_cells_border:
6009
5923
  override = (
6010
5924
  color_tup(self.PAR.ops.table_selected_cells_fg),
@@ -6013,22 +5927,17 @@ class MainTable(tk.Canvas):
6013
5927
  )
6014
5928
  else:
6015
5929
  override = tuple()
5930
+ for r in range(text_start_row, text_end_row):
5931
+ rtopgridln = self.row_positions[r]
5932
+ rbotgridln = self.row_positions[r + 1]
5933
+ if rbotgridln - rtopgridln < self.table_txt_height:
5934
+ continue
5935
+ datarn = self.datarn(r)
6016
5936
 
6017
- rows_ = tuple(range(text_start_row, text_end_row))
6018
- font = self.PAR.ops.table_font
6019
- dd_coords = self.dropdown.get_coords()
6020
- for c in range(text_start_col, text_end_col):
6021
- for r in rows_:
6022
- rtopgridln = self.row_positions[r]
6023
- rbotgridln = self.row_positions[r + 1]
6024
- if rbotgridln - rtopgridln < self.table_txt_height:
6025
- continue
5937
+ for c in range(text_start_col, text_end_col):
6026
5938
  cleftgridln = self.col_positions[c]
6027
5939
  crightgridln = self.col_positions[c + 1]
6028
-
6029
- datarn = self.datarn(r)
6030
5940
  datacn = self.datacn(c)
6031
-
6032
5941
  fill, dd_drawn = self.redraw_highlight_get_text_fg(
6033
5942
  r=r,
6034
5943
  c=c,
@@ -6046,69 +5955,35 @@ class MainTable(tk.Canvas):
6046
5955
  dont_blend=(r, c) == dont_blend,
6047
5956
  alternate_color=alternate_color,
6048
5957
  )
6049
- align = self.get_cell_kwargs(datarn, datacn, key="align")
6050
- if align:
6051
- align = align
6052
- else:
5958
+ if not (align := self.get_cell_kwargs(datarn, datacn, key="align")):
6053
5959
  align = self.align
6054
- kwargs = self.get_cell_kwargs(datarn, datacn, key="dropdown")
6055
- if align == "w":
6056
- draw_x = cleftgridln + 3
6057
- if kwargs:
6058
- mw = crightgridln - cleftgridln - self.table_txt_height - 2
6059
- self.redraw_dropdown(
6060
- cleftgridln,
6061
- rtopgridln,
6062
- crightgridln,
6063
- self.row_positions[r + 1],
6064
- fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
6065
- outline=fill,
6066
- tag=f"dd_{r}_{c}",
6067
- draw_outline=not dd_drawn,
6068
- draw_arrow=mw >= 5,
6069
- open_=dd_coords == (r, c),
6070
- )
6071
- else:
6072
- mw = crightgridln - cleftgridln - 1
6073
- elif align == "e":
6074
- if kwargs:
6075
- mw = crightgridln - cleftgridln - self.table_txt_height - 2
5960
+ if kwargs := self.get_cell_kwargs(datarn, datacn, key="dropdown"):
5961
+ mw = crightgridln - cleftgridln - self.table_txt_height - 2
5962
+ if align == "w":
5963
+ draw_x = cleftgridln + 3
5964
+ elif align == "e":
6076
5965
  draw_x = crightgridln - 5 - self.table_txt_height
6077
- self.redraw_dropdown(
6078
- cleftgridln,
6079
- rtopgridln,
6080
- crightgridln,
6081
- self.row_positions[r + 1],
6082
- fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
6083
- outline=fill,
6084
- tag=f"dd_{r}_{c}",
6085
- draw_outline=not dd_drawn,
6086
- draw_arrow=mw >= 5,
6087
- open_=dd_coords == (r, c),
6088
- )
6089
- else:
6090
- mw = crightgridln - cleftgridln - 1
6091
- draw_x = crightgridln - 3
6092
- elif align == "center":
6093
- if kwargs:
6094
- mw = crightgridln - cleftgridln - self.table_txt_height - 2
5966
+ elif align == "center":
6095
5967
  draw_x = cleftgridln + ceil((crightgridln - cleftgridln - self.table_txt_height) / 2)
6096
- self.redraw_dropdown(
6097
- cleftgridln,
6098
- rtopgridln,
6099
- crightgridln,
6100
- self.row_positions[r + 1],
6101
- fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
6102
- outline=fill,
6103
- tag=f"dd_{r}_{c}",
6104
- draw_outline=not dd_drawn,
6105
- draw_arrow=mw >= 5,
6106
- open_=dd_coords == (r, c),
6107
- )
6108
- else:
6109
- mw = crightgridln - cleftgridln - 1
5968
+ self.redraw_dropdown(
5969
+ cleftgridln,
5970
+ rtopgridln,
5971
+ crightgridln,
5972
+ self.row_positions[r + 1],
5973
+ fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
5974
+ outline=fill,
5975
+ draw_outline=not dd_drawn,
5976
+ draw_arrow=mw >= 5,
5977
+ open_=dd_coords == (r, c),
5978
+ )
5979
+ else:
5980
+ mw = crightgridln - cleftgridln - 1
5981
+ if align == "w":
5982
+ draw_x = cleftgridln + 3
5983
+ elif align == "e":
5984
+ draw_x = crightgridln - 3
5985
+ elif align == "center":
6110
5986
  draw_x = cleftgridln + floor((crightgridln - cleftgridln) / 2)
6111
- if not kwargs:
6112
5987
  kwargs = self.get_cell_kwargs(datarn, datacn, key="checkbox")
6113
5988
  if kwargs and mw > self.table_txt_height + 1:
6114
5989
  box_w = self.table_txt_height + 1
@@ -6118,7 +5993,7 @@ class MainTable(tk.Canvas):
6118
5993
  draw_x += ceil(box_w / 2) + 1
6119
5994
  mw -= box_w + 3
6120
5995
  try:
6121
- draw_check = self.data[datarn][datacn]
5996
+ draw_check = bool(self.data[datarn][datacn])
6122
5997
  except Exception:
6123
5998
  draw_check = False
6124
5999
  self.redraw_checkbox(
@@ -6128,92 +6003,137 @@ class MainTable(tk.Canvas):
6128
6003
  rtopgridln + self.table_txt_height + 3,
6129
6004
  fill=fill if kwargs["state"] == "normal" else self.PAR.ops.table_grid_fg,
6130
6005
  outline="",
6131
- tag="cb",
6132
6006
  draw_check=draw_check,
6133
6007
  )
6134
- lns = self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True).split("\n")
6008
+ lines = self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
6135
6009
  if (
6136
- lns != [""]
6137
- and mw > self.table_txt_width
6138
- and not (
6139
- (align == "w" and draw_x > scrollpos_right)
6140
- or (align == "e" and cleftgridln + 5 > scrollpos_right)
6141
- or (align == "center" and cleftgridln + 5 > scrollpos_right)
6142
- )
6010
+ not lines
6011
+ or mw < self.table_txt_width
6012
+ or (align == "w" and draw_x > scrollpos_right)
6013
+ or (align == "e" and cleftgridln + 5 > scrollpos_right)
6014
+ or (align == "center" and cleftgridln + 5 > scrollpos_right)
6143
6015
  ):
6144
- draw_y = rtopgridln + self.table_first_ln_ins
6145
- start_ln = int((scrollpos_top - rtopgridln) / self.table_xtra_lines_increment)
6146
- if start_ln < 0:
6147
- start_ln = 0
6148
- draw_y += start_ln * self.table_xtra_lines_increment
6149
- if draw_y + self.table_half_txt_height - 1 <= rbotgridln and len(lns) > start_ln:
6150
- for txt in islice(lns, start_ln, None):
6151
- if self.hidd_text:
6152
- iid, showing = self.hidd_text.popitem()
6153
- self.coords(iid, draw_x, draw_y)
6154
- if showing:
6155
- self.itemconfig(
6156
- iid,
6157
- text=txt,
6158
- fill=fill,
6159
- font=font,
6160
- anchor=align,
6161
- )
6162
- else:
6163
- self.itemconfig(
6164
- iid,
6165
- text=txt,
6166
- fill=fill,
6167
- font=font,
6168
- anchor=align,
6169
- state="normal",
6170
- )
6171
- self.tag_raise(iid)
6016
+ continue
6017
+ lines = lines.split("\n")
6018
+ start_ln = max(0, int((scrollpos_top - rtopgridln) / self.table_xtra_lines_increment))
6019
+ draw_y = rtopgridln + self.table_first_ln_ins + start_ln * self.table_xtra_lines_increment
6020
+ if draw_y + self.table_half_txt_height - 1 <= rbotgridln and len(lines) >= start_ln:
6021
+ for txt in islice(lines, start_ln, None):
6022
+ if self.hidd_text:
6023
+ iid, showing = self.hidd_text.popitem()
6024
+ self.coords(iid, draw_x, draw_y)
6025
+ if showing:
6026
+ self.itemconfig(
6027
+ iid,
6028
+ text=txt,
6029
+ fill=fill,
6030
+ font=font,
6031
+ anchor=align,
6032
+ )
6172
6033
  else:
6173
- iid = self.create_text(
6174
- draw_x,
6175
- draw_y,
6034
+ self.itemconfig(
6035
+ iid,
6176
6036
  text=txt,
6177
6037
  fill=fill,
6178
6038
  font=font,
6179
6039
  anchor=align,
6180
- tag="t",
6040
+ state="normal",
6181
6041
  )
6182
- self.disp_text[iid] = True
6183
- wd = self.bbox(iid)
6184
- wd = wd[2] - wd[0]
6185
- if wd > mw:
6186
- if align == "w":
6187
- txt = txt[: int(len(txt) * (mw / wd))]
6042
+ self.tag_raise(iid)
6043
+ else:
6044
+ iid = self.create_text(
6045
+ draw_x,
6046
+ draw_y,
6047
+ text=txt,
6048
+ fill=fill,
6049
+ font=font,
6050
+ anchor=align,
6051
+ tag="t",
6052
+ )
6053
+ self.disp_text[iid] = True
6054
+ wd = self.bbox(iid)
6055
+ if (wd := wd[2] - wd[0]) > mw:
6056
+ if align == "w":
6057
+ txt = txt[: int(len(txt) * (mw / wd))]
6058
+ self.itemconfig(iid, text=txt)
6059
+ wd = self.bbox(iid)
6060
+ while wd[2] - wd[0] > mw:
6061
+ txt = txt[:-1]
6188
6062
  self.itemconfig(iid, text=txt)
6189
6063
  wd = self.bbox(iid)
6190
- while wd[2] - wd[0] > mw:
6191
- txt = txt[:-1]
6192
- self.itemconfig(iid, text=txt)
6193
- wd = self.bbox(iid)
6194
- elif align == "e":
6195
- txt = txt[len(txt) - int(len(txt) * (mw / wd)) :]
6064
+ elif align == "e":
6065
+ txt = txt[len(txt) - int(len(txt) * (mw / wd)) :]
6066
+ self.itemconfig(iid, text=txt)
6067
+ wd = self.bbox(iid)
6068
+ while wd[2] - wd[0] > mw:
6069
+ txt = txt[1:]
6196
6070
  self.itemconfig(iid, text=txt)
6197
6071
  wd = self.bbox(iid)
6198
- while wd[2] - wd[0] > mw:
6199
- txt = txt[1:]
6200
- self.itemconfig(iid, text=txt)
6201
- wd = self.bbox(iid)
6202
- elif align == "center":
6203
- self.c_align_cyc = cycle(self.centre_alignment_text_mod_indexes)
6204
- tmod = ceil((len(txt) - int(len(txt) * (mw / wd))) / 2)
6205
- txt = txt[tmod - 1 : -tmod]
6072
+ elif align == "center":
6073
+ tmod = ceil((len(txt) - int(len(txt) * (mw / wd))) / 2)
6074
+ txt = txt[tmod - 1 : -tmod]
6075
+ self.itemconfig(iid, text=txt)
6076
+ wd = self.bbox(iid)
6077
+ while wd[2] - wd[0] > mw:
6078
+ txt = txt[next(self.c_align_cyc)]
6206
6079
  self.itemconfig(iid, text=txt)
6207
6080
  wd = self.bbox(iid)
6208
- while wd[2] - wd[0] > mw:
6209
- txt = txt[next(self.c_align_cyc)]
6210
- self.itemconfig(iid, text=txt)
6211
- wd = self.bbox(iid)
6212
- self.coords(iid, draw_x, draw_y)
6213
- draw_y += self.table_xtra_lines_increment
6214
- if draw_y + self.table_half_txt_height - 1 > rbotgridln:
6215
- break
6216
- if redraw_table:
6081
+ self.coords(iid, draw_x, draw_y)
6082
+ draw_y += self.table_xtra_lines_increment
6083
+ if draw_y + self.table_half_txt_height - 1 > rbotgridln:
6084
+ break
6085
+ # manage horizontal grid lines
6086
+ if self.PAR.ops.show_horizontal_grid and row_pos_exists:
6087
+ if self.PAR.ops.horizontal_grid_to_end_of_window:
6088
+ x_grid_stop = scrollpos_right + can_width
6089
+ else:
6090
+ if last_col_line_pos > scrollpos_right:
6091
+ x_grid_stop = x_stop + 1
6092
+ else:
6093
+ x_grid_stop = x_stop - 1
6094
+ self.redraw_gridline(
6095
+ points=tuple(
6096
+ chain.from_iterable(
6097
+ (
6098
+ scrollpos_left - 1,
6099
+ self.row_positions[r],
6100
+ x_grid_stop,
6101
+ self.row_positions[r],
6102
+ scrollpos_left - 1,
6103
+ self.row_positions[r],
6104
+ scrollpos_left - 1,
6105
+ self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
6106
+ )
6107
+ for r in range(grid_start_row, grid_end_row)
6108
+ )
6109
+ )
6110
+ )
6111
+ # manage vertical grid lines
6112
+ if self.PAR.ops.show_vertical_grid and col_pos_exists:
6113
+ if self.PAR.ops.vertical_grid_to_end_of_window:
6114
+ y_grid_stop = scrollpos_bot + can_height
6115
+ else:
6116
+ if last_row_line_pos > scrollpos_bot:
6117
+ y_grid_stop = y_stop + 1
6118
+ else:
6119
+ y_grid_stop = y_stop - 1
6120
+ self.redraw_gridline(
6121
+ points=tuple(
6122
+ chain.from_iterable(
6123
+ (
6124
+ self.col_positions[c],
6125
+ scrollpos_top - 1,
6126
+ self.col_positions[c],
6127
+ y_grid_stop,
6128
+ self.col_positions[c],
6129
+ scrollpos_top - 1,
6130
+ self.col_positions[c + 1] if len(self.col_positions) - 1 > c else self.col_positions[c],
6131
+ scrollpos_top - 1,
6132
+ )
6133
+ for c in range(grid_start_col, grid_end_col)
6134
+ )
6135
+ ),
6136
+ )
6217
6137
  for dct in (
6218
6138
  self.hidd_text,
6219
6139
  self.hidd_high,
@@ -6231,6 +6151,10 @@ class MainTable(tk.Canvas):
6231
6151
  self.tag_raise(box.bd_iid)
6232
6152
  if self.selected:
6233
6153
  self.tag_raise(self.selected.iid)
6154
+ if self.RI.disp_resize_lines:
6155
+ self.tag_raise("rh")
6156
+ if self.CH.disp_resize_lines:
6157
+ self.tag_raise("rw")
6234
6158
  if redraw_header and self.show_header:
6235
6159
  self.CH.redraw_grid_and_text(
6236
6160
  last_col_line_pos=last_col_line_pos,
@@ -6310,7 +6234,7 @@ class MainTable(tk.Canvas):
6310
6234
  # set current to a particular existing selection box
6311
6235
  if isinstance(item, int) and item in self.selection_boxes:
6312
6236
  selection_box = self.selection_boxes[item]
6313
- r1, c1, r2, c2 = selection_box.coords
6237
+ r1, c1, _, _ = selection_box.coords
6314
6238
  if box_created(r1 if r is None else r, c1 if c is None else c, selection_box):
6315
6239
  return
6316
6240
 
@@ -6729,7 +6653,7 @@ class MainTable(tk.Canvas):
6729
6653
 
6730
6654
  def get_redraw_selections(self, startr: int, endr: int, startc: int, endc: int) -> dict:
6731
6655
  d = defaultdict(set)
6732
- for item, box in self.get_selection_items():
6656
+ for _, box in self.get_selection_items():
6733
6657
  r1, c1, r2, c2 = box.coords
6734
6658
  if box.type_ == "cells":
6735
6659
  for r in range(startr, endr):
@@ -6767,7 +6691,7 @@ class MainTable(tk.Canvas):
6767
6691
  if get_cells:
6768
6692
  s = {
6769
6693
  (r, c)
6770
- for item, box in self.get_selection_items(cells=False, columns=False)
6694
+ for _, box in self.get_selection_items(cells=False, columns=False)
6771
6695
  for r in range(box.coords.from_r, box.coords.upto_r)
6772
6696
  for c in range(0, len(self.col_positions) - 1)
6773
6697
  }
@@ -6776,7 +6700,7 @@ class MainTable(tk.Canvas):
6776
6700
  else:
6777
6701
  s = {
6778
6702
  r
6779
- for item, box in self.get_selection_items(cells=False, columns=False)
6703
+ for _, box in self.get_selection_items(cells=False, columns=False)
6780
6704
  for r in range(box.coords.from_r, box.coords.upto_r)
6781
6705
  }
6782
6706
  if get_cells_as_rows:
@@ -6791,7 +6715,7 @@ class MainTable(tk.Canvas):
6791
6715
  if get_cells:
6792
6716
  s = {
6793
6717
  (r, c)
6794
- for item, box in self.get_selection_items(cells=False, rows=False)
6718
+ for _, box in self.get_selection_items(cells=False, rows=False)
6795
6719
  for r in range(0, len(self.row_positions) - 1)
6796
6720
  for c in range(box.coords.from_c, box.coords.upto_c)
6797
6721
  }
@@ -6800,7 +6724,7 @@ class MainTable(tk.Canvas):
6800
6724
  else:
6801
6725
  s = {
6802
6726
  c
6803
- for item, box in self.get_selection_items(cells=False, rows=False)
6727
+ for _, box in self.get_selection_items(cells=False, rows=False)
6804
6728
  for c in range(box.coords.from_c, box.coords.upto_c)
6805
6729
  }
6806
6730
  if get_cells_as_cols:
@@ -6814,7 +6738,7 @@ class MainTable(tk.Canvas):
6814
6738
  ) -> set[tuple[int, int]]:
6815
6739
  return {
6816
6740
  (r, c)
6817
- for item, box in self.get_selection_items(rows=get_rows, columns=get_cols)
6741
+ for _, box in self.get_selection_items(rows=get_rows, columns=get_cols)
6818
6742
  for r in range(box.coords.from_r, box.coords.upto_r)
6819
6743
  for c in range(box.coords.from_c, box.coords.upto_c)
6820
6744
  }
@@ -6826,16 +6750,16 @@ class MainTable(tk.Canvas):
6826
6750
  ) -> Generator[tuple[int, int]]:
6827
6751
  yield from (
6828
6752
  (r, c)
6829
- for item, box in self.get_selection_items(rows=get_rows, columns=get_cols)
6753
+ for _, box in self.get_selection_items(rows=get_rows, columns=get_cols)
6830
6754
  for r in range(box.coords.from_r, box.coords.upto_r)
6831
6755
  for c in range(box.coords.from_c, box.coords.upto_c)
6832
6756
  )
6833
6757
 
6834
6758
  def get_all_selection_boxes(self) -> tuple[tuple[int, int, int, int]]:
6835
- return tuple(box.coords for item, box in self.get_selection_items())
6759
+ return tuple(box.coords for _, box in self.get_selection_items())
6836
6760
 
6837
6761
  def get_all_selection_boxes_with_types(self) -> list[tuple[tuple[int, int, int, int], str]]:
6838
- return [Box_st(box.coords, box.type_) for item, box in self.get_selection_items()]
6762
+ return [Box_st(box.coords, box.type_) for _, box in self.get_selection_items()]
6839
6763
 
6840
6764
  def all_selected(self) -> bool:
6841
6765
  return any(
@@ -6855,7 +6779,7 @@ class MainTable(tk.Canvas):
6855
6779
  and isinstance(c, int)
6856
6780
  and any(
6857
6781
  box.coords.from_r <= r and box.coords.upto_r > r and box.coords.from_c <= c and box.coords.upto_c > c
6858
- for item, box in self.get_selection_items(
6782
+ for _, box in self.get_selection_items(
6859
6783
  rows=inc_rows,
6860
6784
  columns=inc_cols,
6861
6785
  )
@@ -6865,7 +6789,7 @@ class MainTable(tk.Canvas):
6865
6789
  def col_selected(self, c: int, cells: bool = False) -> bool:
6866
6790
  return isinstance(c, int) and any(
6867
6791
  box.coords.from_c <= c and box.coords.upto_c > c
6868
- for item, box in self.get_selection_items(
6792
+ for _, box in self.get_selection_items(
6869
6793
  cells=cells,
6870
6794
  rows=False,
6871
6795
  )
@@ -6874,7 +6798,7 @@ class MainTable(tk.Canvas):
6874
6798
  def row_selected(self, r: int, cells: bool = False) -> bool:
6875
6799
  return isinstance(r, int) and any(
6876
6800
  box.coords.from_r <= r and box.coords.upto_r > r
6877
- for item, box in self.get_selection_items(
6801
+ for _, box in self.get_selection_items(
6878
6802
  cells=cells,
6879
6803
  columns=False,
6880
6804
  )
@@ -6888,7 +6812,7 @@ class MainTable(tk.Canvas):
6888
6812
  ) -> list[int]:
6889
6813
  return [
6890
6814
  item
6891
- for item, box in self.get_selection_items(
6815
+ for item, _ in self.get_selection_items(
6892
6816
  columns=not exclude_columns,
6893
6817
  rows=not exclude_rows,
6894
6818
  cells=not exclude_cells,
@@ -7046,10 +6970,10 @@ class MainTable(tk.Canvas):
7046
6970
  )
7047
6971
  > curr_height
7048
6972
  ):
7049
- new_height = curr_height + self.table_xtra_lines_increment
7050
- space_bot = self.get_space_bot(r)
7051
- if new_height > space_bot:
7052
- new_height = space_bot
6973
+ new_height = min(
6974
+ curr_height + self.table_xtra_lines_increment,
6975
+ self.scrollregion[3] - self.scrollregion[1] - self.row_positions[r],
6976
+ )
7053
6977
  if new_height != curr_height:
7054
6978
  self.text_editor.window.config(height=new_height)
7055
6979
  if self.dropdown.open and self.dropdown.get_coords() == (r, c):
@@ -7284,10 +7208,8 @@ class MainTable(tk.Canvas):
7284
7208
  sheet_h = int(
7285
7209
  self.row_positions[-1] + 1 + self.PAR.ops.empty_vertical - (self.row_positions[r] + text_editor_h)
7286
7210
  )
7287
- if win_h > 0:
7288
- win_h -= 1
7289
- if sheet_h > 0:
7290
- sheet_h -= 1
7211
+ win_h = max(0, win_h - 1)
7212
+ sheet_h = max(0, sheet_h - 1)
7291
7213
  return win_h if win_h >= sheet_h else sheet_h
7292
7214
 
7293
7215
  def get_dropdown_height_anchor(self, r: int, c: int, text_editor_h: int | None = None) -> tuple:
@@ -7301,8 +7223,7 @@ class MainTable(tk.Canvas):
7301
7223
  win_h += self.min_row_height
7302
7224
  if i == 5:
7303
7225
  break
7304
- if win_h > 500:
7305
- win_h = 500
7226
+ win_h = min(win_h, 500)
7306
7227
  space_bot = self.get_space_bot(r, text_editor_h)
7307
7228
  space_top = int(self.row_positions[r])
7308
7229
  anchor = "nw"
@@ -7392,7 +7313,7 @@ class MainTable(tk.Canvas):
7392
7313
  self.itemconfig(self.dropdown.canvas_id, state="normal", anchor=anchor)
7393
7314
  self.dropdown.window.tkraise()
7394
7315
  else:
7395
- self.dropdown.window = self.PAR.dropdown_class(
7316
+ self.dropdown.window = self.PAR._dropdown_cls(
7396
7317
  self.winfo_toplevel(),
7397
7318
  **reset_kwargs,
7398
7319
  close_dropdown_window=self.close_dropdown_window,
@@ -7437,12 +7358,11 @@ class MainTable(tk.Canvas):
7437
7358
  datacn = self.datacn(c)
7438
7359
  datarn = self.datarn(r)
7439
7360
  kwargs = self.get_cell_kwargs(datarn, datacn, key="dropdown")
7440
- pre_edit_value = self.get_cell_data(datarn, datacn)
7441
7361
  event_data = event_dict(
7442
7362
  name="end_edit_table",
7443
7363
  sheet=self.PAR.name,
7444
7364
  widget=self,
7445
- cells_table={(datarn, datacn): pre_edit_value},
7365
+ cells_table={(datarn, datacn): self.get_cell_data(datarn, datacn)},
7446
7366
  key="??",
7447
7367
  value=selection,
7448
7368
  loc=Loc(r, c),
@@ -7451,30 +7371,12 @@ class MainTable(tk.Canvas):
7451
7371
  boxes=self.get_boxes(),
7452
7372
  selected=self.selected,
7453
7373
  )
7454
- if kwargs["select_function"] is not None:
7455
- kwargs["select_function"](event_data)
7456
- if self.edit_validation_func:
7457
- selection, edited = self.edit_validation_func(event_data), False
7458
- if selection is not None:
7459
- edited = self.set_cell_data_undo(
7460
- r,
7461
- c,
7462
- datarn=datarn,
7463
- datacn=datacn,
7464
- value=selection,
7465
- redraw=not redraw,
7466
- )
7467
- else:
7468
- edited = self.set_cell_data_undo(
7469
- r,
7470
- c,
7471
- datarn=datarn,
7472
- datacn=datacn,
7473
- value=selection,
7474
- redraw=not redraw,
7475
- )
7476
- if edited:
7477
- try_binding(self.extra_end_edit_cell_func, event_data)
7374
+ try_binding(kwargs["select_function"], event_data)
7375
+ selection = selection if not self.edit_validation_func else self.edit_validation_func(event_data)
7376
+ if selection is not None:
7377
+ edited = self.set_cell_data_undo(r, c, datarn=datarn, datacn=datacn, value=selection, redraw=not redraw)
7378
+ if edited:
7379
+ try_binding(self.extra_end_edit_cell_func, event_data)
7478
7380
  self.recreate_all_selection_boxes()
7479
7381
  self.focus_set()
7480
7382
  self.hide_text_editor_and_dropdown(redraw=redraw)