tksheet 7.2.1__py3-none-any.whl → 7.2.3__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/column_headers.py CHANGED
@@ -4,6 +4,7 @@ import tkinter as tk
4
4
  from collections import defaultdict
5
5
  from collections.abc import (
6
6
  Callable,
7
+ Hashable,
7
8
  Sequence,
8
9
  )
9
10
  from functools import (
@@ -12,8 +13,12 @@ from functools import (
12
13
  from itertools import (
13
14
  cycle,
14
15
  islice,
16
+ repeat,
15
17
  )
16
18
  from math import ceil, floor
19
+ from operator import (
20
+ itemgetter,
21
+ )
17
22
  from typing import Literal
18
23
 
19
24
  from .colors import (
@@ -134,7 +139,7 @@ class ColumnHeaders(tk.Canvas):
134
139
  else:
135
140
  super().event_generate(*args, **kwargs)
136
141
 
137
- def basic_bindings(self, enable: bool = True):
142
+ def basic_bindings(self, enable: bool = True) -> None:
138
143
  if enable:
139
144
  self.bind("<Motion>", self.mouse_motion)
140
145
  self.bind("<ButtonPress-1>", self.b1_press)
@@ -158,22 +163,26 @@ class ColumnHeaders(tk.Canvas):
158
163
  self.unbind("<Button-4>")
159
164
  self.unbind("<Button-5>")
160
165
 
161
- def mousewheel(self, event: object):
162
- maxlines = 0
166
+ def mousewheel(self, event: object) -> None:
163
167
  if isinstance(self.MT._headers, int):
164
- if len(self.MT.data) > self.MT._headers:
165
- maxlines = max(
168
+ maxlines = max(
169
+ (
166
170
  len(
167
171
  self.MT.get_valid_cell_data_as_str(self.MT._headers, datacn, get_displayed=True)
168
172
  .rstrip()
169
173
  .split("\n")
170
174
  )
171
175
  for datacn in range(len(self.MT.data[self.MT._headers]))
172
- )
176
+ ),
177
+ default=0,
178
+ )
173
179
  elif isinstance(self.MT._headers, (list, tuple)):
174
180
  maxlines = max(
175
- len(e.rstrip().split("\n")) if isinstance(e, str) else len(f"{e}".rstrip().split("\n"))
176
- for e in self.MT._headers
181
+ (
182
+ len(e.rstrip().split("\n")) if isinstance(e, str) else len(f"{e}".rstrip().split("\n"))
183
+ for e in self.MT._headers
184
+ ),
185
+ default=0,
177
186
  )
178
187
  if maxlines == 1:
179
188
  maxlines = 0
@@ -390,7 +399,7 @@ class ColumnHeaders(tk.Canvas):
390
399
  self.MT.reset_mouse_motion_creations()
391
400
  try_binding(self.extra_motion_func, event)
392
401
 
393
- def double_b1(self, event: object):
402
+ def double_b1(self, event: object) -> None:
394
403
  self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
395
404
  self.focus_set()
396
405
  if (
@@ -430,7 +439,7 @@ class ColumnHeaders(tk.Canvas):
430
439
  self.mouse_motion(event)
431
440
  try_binding(self.extra_double_b1_func, event)
432
441
 
433
- def b1_press(self, event: object):
442
+ def b1_press(self, event: object) -> None:
434
443
  self.MT.unbind("<MouseWheel>")
435
444
  self.focus_set()
436
445
  self.closed_dropdown = self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
@@ -495,7 +504,7 @@ class ColumnHeaders(tk.Canvas):
495
504
  self.toggle_select_col(c, redraw=True)
496
505
  try_binding(self.extra_b1_press_func, event)
497
506
 
498
- def b1_motion(self, event: object):
507
+ def b1_motion(self, event: object) -> None:
499
508
  x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
500
509
  if self.width_resizing_enabled and self.rsz_w is not None and self.currently_resizing_width:
501
510
  x = self.canvasx(event.x)
@@ -593,13 +602,13 @@ class ColumnHeaders(tk.Canvas):
593
602
  self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=False)
594
603
  try_binding(self.extra_b1_motion_func, event)
595
604
 
596
- def get_b1_motion_box(self, start_col, end_col):
605
+ def get_b1_motion_box(self, start_col: int, end_col: int) -> tuple[int, int, int, int, Literal["columns"]]:
597
606
  if end_col >= start_col:
598
607
  return 0, start_col, len(self.MT.row_positions) - 1, end_col + 1, "columns"
599
608
  elif end_col < start_col:
600
609
  return 0, end_col, len(self.MT.row_positions) - 1, start_col + 1, "columns"
601
610
 
602
- def ctrl_b1_motion(self, event: object):
611
+ def ctrl_b1_motion(self, event: object) -> None:
603
612
  x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
604
613
  if (
605
614
  self.drag_and_drop_enabled
@@ -653,7 +662,7 @@ class ColumnHeaders(tk.Canvas):
653
662
  elif not self.MT.ctrl_select_enabled:
654
663
  self.b1_motion(event)
655
664
 
656
- def drag_and_drop_motion(self, event: object):
665
+ def drag_and_drop_motion(self, event: object) -> float:
657
666
  x = event.x
658
667
  wend = self.winfo_width()
659
668
  xcheck = self.xview()
@@ -997,7 +1006,7 @@ class ColumnHeaders(tk.Canvas):
997
1006
  self.hidd_boxes.add(item)
998
1007
  self.itemconfig(item, state="hidden")
999
1008
 
1000
- def get_cell_dimensions(self, datacn):
1009
+ def get_cell_dimensions(self, datacn: int) -> tuple[int, int]:
1001
1010
  txt = self.get_valid_cell_data_as_str(datacn, fix=False)
1002
1011
  if txt:
1003
1012
  self.MT.txt_measure_canvas.itemconfig(
@@ -1015,29 +1024,28 @@ class ColumnHeaders(tk.Canvas):
1015
1024
  return w + self.MT.header_txt_height, h
1016
1025
  return w, h
1017
1026
 
1018
- def set_height_of_header_to_text(self, text=None, only_increase=False):
1019
- if (
1020
- text is None
1021
- and not self.MT._headers
1022
- and isinstance(self.MT._headers, list)
1023
- or isinstance(self.MT._headers, int)
1024
- and self.MT._headers >= len(self.MT.data)
1027
+ def set_height_of_header_to_text(
1028
+ self,
1029
+ text: None | str = None,
1030
+ only_if_too_small: bool = False,
1031
+ ) -> int:
1032
+ h = self.MT.min_header_height
1033
+ if (text is None and not self.MT._headers and isinstance(self.MT._headers, list)) or (
1034
+ isinstance(self.MT._headers, int) and self.MT._headers >= len(self.MT.data)
1025
1035
  ):
1026
- return
1036
+ return h
1037
+ self.fix_header()
1027
1038
  qconf = self.MT.txt_measure_canvas.itemconfig
1028
1039
  qbbox = self.MT.txt_measure_canvas.bbox
1029
1040
  qtxtm = self.MT.txt_measure_canvas_text
1030
1041
  qfont = self.PAR.ops.header_font
1031
- new_height = self.MT.min_header_height
1032
1042
  default_header_height = self.MT.get_default_header_height()
1033
- self.fix_header()
1034
- if text is not None:
1035
- if text:
1036
- qconf(qtxtm, text=text, font=qfont)
1037
- b = qbbox(qtxtm)
1038
- if (h := b[3] - b[1] + 5) > new_height:
1039
- new_height = h
1040
- else:
1043
+ if text is not None and text:
1044
+ qconf(qtxtm, text=text, font=qfont)
1045
+ b = qbbox(qtxtm)
1046
+ if (th := b[3] - b[1] + 5) > h:
1047
+ h = th
1048
+ elif text is None:
1041
1049
  if self.MT.all_columns_displayed:
1042
1050
  if isinstance(self.MT._headers, list):
1043
1051
  iterable = range(len(self.MT._headers))
@@ -1045,141 +1053,142 @@ class ColumnHeaders(tk.Canvas):
1045
1053
  iterable = range(len(self.MT.data[self.MT._headers]))
1046
1054
  else:
1047
1055
  iterable = self.MT.displayed_columns
1048
- if isinstance(self.MT._headers, list):
1049
- for datacn in iterable:
1050
- w_, h = self.get_cell_dimensions(datacn)
1051
- if h < self.MT.min_header_height:
1052
- h = int(self.MT.min_header_height)
1053
- elif h > self.MT.max_header_height:
1054
- h = int(self.MT.max_header_height)
1055
- if h > new_height:
1056
- new_height = h
1056
+ if (
1057
+ isinstance(self.MT._headers, list)
1058
+ and (th := max(map(itemgetter(0), map(self.get_cell_dimensions, iterable)), default=h)) > h
1059
+ ):
1060
+ h = th
1057
1061
  elif isinstance(self.MT._headers, int):
1058
1062
  datarn = self.MT._headers
1059
1063
  for datacn in iterable:
1060
- txt = self.MT.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
1061
- if txt:
1064
+ if txt := self.MT.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True):
1062
1065
  qconf(qtxtm, text=txt, font=qfont)
1063
1066
  b = qbbox(qtxtm)
1064
- h = b[3] - b[1] + 5
1067
+ th = b[3] - b[1] + 5
1065
1068
  else:
1066
- h = default_header_height
1067
- if h < self.MT.min_header_height:
1068
- h = int(self.MT.min_header_height)
1069
- elif h > self.MT.max_header_height:
1070
- h = int(self.MT.max_header_height)
1071
- if h > new_height:
1072
- new_height = h
1069
+ th = default_header_height
1070
+ if th > h:
1071
+ h = th
1073
1072
  space_bot = self.MT.get_space_bot(0)
1074
- if new_height > space_bot and space_bot > self.MT.min_header_height:
1075
- new_height = space_bot
1076
- if not only_increase or (only_increase and new_height > self.current_height):
1077
- self.set_height(new_height, set_TL=True)
1073
+ if h > space_bot and space_bot > self.MT.min_header_height:
1074
+ h = space_bot
1075
+ if h < self.MT.min_header_height:
1076
+ h = int(self.MT.min_header_height)
1077
+ elif h > self.MT.max_header_height:
1078
+ h = int(self.MT.max_header_height)
1079
+ if not only_if_too_small or (only_if_too_small and h > self.current_height):
1080
+ self.set_height(h, set_TL=True)
1078
1081
  self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
1079
- return new_height
1082
+ return h
1080
1083
 
1081
- def set_col_width(
1084
+ def get_col_text_width(
1082
1085
  self,
1083
- col,
1084
- width=None,
1085
- only_set_if_too_small=False,
1086
- displayed_only=False,
1087
- recreate=True,
1088
- return_new_width=False,
1089
- ):
1090
- if col < 0:
1091
- return
1092
- qconf = self.MT.txt_measure_canvas.itemconfig
1093
- qbbox = self.MT.txt_measure_canvas.bbox
1094
- qtxtm = self.MT.txt_measure_canvas_text
1095
- qtxth = self.MT.table_txt_height
1096
- qfont = self.PAR.ops.table_font
1086
+ col: int,
1087
+ visible_only: bool = False,
1088
+ only_if_too_small: bool = False,
1089
+ ) -> int:
1097
1090
  self.fix_header()
1098
- if width is None:
1099
- w = self.MT.min_column_width
1100
- hw = self.MT.min_column_width
1091
+ w = self.MT.min_column_width
1092
+ datacn = col if self.MT.all_columns_displayed else self.MT.displayed_columns[col]
1093
+ # header
1094
+ hw, hh_ = self.get_cell_dimensions(datacn)
1095
+ # table
1096
+ if self.MT.data:
1101
1097
  if self.MT.all_rows_displayed:
1102
- if displayed_only:
1103
- x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
1104
- start_row, end_row = self.MT.get_visible_rows(y1, y2)
1098
+ if visible_only:
1099
+ iterable = range(*self.MT.visible_text_rows)
1105
1100
  else:
1106
- start_row, end_row = 0, len(self.MT.data)
1107
- iterable = range(start_row, end_row)
1101
+ iterable = range(0, len(self.MT.data))
1108
1102
  else:
1109
- if displayed_only:
1110
- x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
1111
- start_row, end_row = self.MT.get_visible_rows(y1, y2)
1103
+ if visible_only:
1104
+ start_row, end_row = self.MT.visible_text_rows
1112
1105
  else:
1113
1106
  start_row, end_row = 0, len(self.MT.displayed_rows)
1114
1107
  iterable = self.MT.displayed_rows[start_row:end_row]
1115
- datacn = col if self.MT.all_columns_displayed else self.MT.displayed_columns[col]
1116
- # header
1117
- hw, hh_ = self.get_cell_dimensions(datacn)
1118
- # table
1119
- if self.MT.data:
1120
- for datarn in iterable:
1121
- txt = self.MT.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
1122
- if txt:
1123
- qconf(qtxtm, text=txt, font=qfont)
1124
- b = qbbox(qtxtm)
1125
- if self.MT.get_cell_kwargs(datarn, datacn, key="dropdown") or self.MT.get_cell_kwargs(
1126
- datarn, datacn, key="checkbox"
1127
- ):
1128
- tw = b[2] - b[0] + qtxth + 7
1129
- else:
1130
- tw = b[2] - b[0] + 7
1131
- if tw > w:
1132
- w = tw
1133
- if w > hw:
1134
- new_width = w
1135
- else:
1136
- new_width = hw
1137
- else:
1138
- new_width = int(width)
1139
- if new_width <= self.MT.min_column_width:
1140
- new_width = int(self.MT.min_column_width)
1141
- elif new_width > self.MT.max_column_width:
1142
- new_width = int(self.MT.max_column_width)
1143
- if only_set_if_too_small:
1144
- if new_width <= self.MT.col_positions[col + 1] - self.MT.col_positions[col]:
1145
- return self.MT.col_positions[col + 1] - self.MT.col_positions[col]
1146
- if not return_new_width:
1147
- new_col_pos = self.MT.col_positions[col] + new_width
1148
- increment = new_col_pos - self.MT.col_positions[col + 1]
1149
- self.MT.col_positions[col + 2 :] = [
1150
- e + increment for e in islice(self.MT.col_positions, col + 2, len(self.MT.col_positions))
1151
- ]
1152
- self.MT.col_positions[col + 1] = new_col_pos
1153
- if recreate:
1154
- self.MT.recreate_all_selection_boxes()
1155
- return new_width
1108
+ qconf = self.MT.txt_measure_canvas.itemconfig
1109
+ qbbox = self.MT.txt_measure_canvas.bbox
1110
+ qtxtm = self.MT.txt_measure_canvas_text
1111
+ qtxth = self.MT.table_txt_height
1112
+ qfont = self.PAR.ops.table_font
1113
+ for datarn in iterable:
1114
+ if txt := self.MT.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True):
1115
+ qconf(qtxtm, text=txt, font=qfont)
1116
+ b = qbbox(qtxtm)
1117
+ if (
1118
+ self.MT.get_cell_kwargs(datarn, datacn, key="dropdown")
1119
+ or self.MT.get_cell_kwargs(datarn, datacn, key="checkbox")
1120
+ ) and (tw := b[2] - b[0] + qtxth + 7) > w:
1121
+ w = tw
1122
+ elif (tw := b[2] - b[0] + 7) > w:
1123
+ w = tw
1124
+ if hw > w:
1125
+ w = hw
1126
+ if only_if_too_small and w < self.MT.col_positions[col + 1] - self.MT.col_positions[col]:
1127
+ w = self.MT.col_positions[col + 1] - self.MT.col_positions[col]
1128
+ if w <= self.MT.min_column_width:
1129
+ w = int(self.MT.min_column_width)
1130
+ elif w > self.MT.max_column_width:
1131
+ w = int(self.MT.max_column_width)
1132
+ return w
1156
1133
 
1157
- def set_width_of_all_cols(self, width=None, only_set_if_too_small=False, recreate=True):
1134
+ def set_col_width(
1135
+ self,
1136
+ col: int,
1137
+ width: None | int = None,
1138
+ only_if_too_small: bool = False,
1139
+ visible_only: bool = False,
1140
+ recreate: bool = True,
1141
+ ) -> int:
1142
+ if width is None:
1143
+ width = self.get_col_text_width(col=col, visible_only=visible_only)
1144
+ if width <= self.MT.min_column_width:
1145
+ width = int(self.MT.min_column_width)
1146
+ elif width > self.MT.max_column_width:
1147
+ width = int(self.MT.max_column_width)
1148
+ if only_if_too_small and width <= self.MT.col_positions[col + 1] - self.MT.col_positions[col]:
1149
+ return self.MT.col_positions[col + 1] - self.MT.col_positions[col]
1150
+ new_col_pos = self.MT.col_positions[col] + width
1151
+ increment = new_col_pos - self.MT.col_positions[col + 1]
1152
+ self.MT.col_positions[col + 2 :] = [
1153
+ e + increment for e in islice(self.MT.col_positions, col + 2, len(self.MT.col_positions))
1154
+ ]
1155
+ self.MT.col_positions[col + 1] = new_col_pos
1156
+ if recreate:
1157
+ self.MT.recreate_all_selection_boxes()
1158
+ return width
1159
+
1160
+ def set_width_of_all_cols(
1161
+ self,
1162
+ width: None | int = None,
1163
+ only_if_too_small: bool = False,
1164
+ recreate: bool = True,
1165
+ ) -> None:
1158
1166
  if width is None:
1159
1167
  if self.MT.all_columns_displayed:
1160
1168
  iterable = range(self.MT.total_data_cols())
1161
1169
  else:
1162
1170
  iterable = range(len(self.MT.displayed_columns))
1163
1171
  self.MT.set_col_positions(
1164
- itr=(
1165
- self.set_col_width(
1166
- cn,
1167
- only_set_if_too_small=only_set_if_too_small,
1168
- recreate=False,
1169
- return_new_width=True,
1170
- )
1171
- for cn in iterable
1172
- )
1172
+ itr=(self.get_col_text_width(cn, only_if_too_small=only_if_too_small) for cn in iterable)
1173
1173
  )
1174
1174
  elif width is not None:
1175
1175
  if self.MT.all_columns_displayed:
1176
- self.MT.set_col_positions(itr=(width for cn in range(self.MT.total_data_cols())))
1176
+ self.MT.set_col_positions(itr=repeat(width, self.MT.total_data_cols()))
1177
1177
  else:
1178
- self.MT.set_col_positions(itr=(width for cn in range(len(self.MT.displayed_columns))))
1178
+ self.MT.set_col_positions(itr=repeat(width, len(self.MT.displayed_columns)))
1179
1179
  if recreate:
1180
1180
  self.MT.recreate_all_selection_boxes()
1181
1181
 
1182
- def redraw_highlight_get_text_fg(self, fc, sc, c, c_2, c_3, selections, datacn):
1182
+ def redraw_highlight_get_text_fg(
1183
+ self,
1184
+ fc: float,
1185
+ sc: float,
1186
+ c: int,
1187
+ c_2: str,
1188
+ c_3: str,
1189
+ selections: dict,
1190
+ datacn: int,
1191
+ ) -> tuple[str, bool]:
1183
1192
  redrawn = False
1184
1193
  kwargs = self.get_cell_kwargs(datacn, key="highlight")
1185
1194
  if kwargs:
@@ -1236,7 +1245,16 @@ class ColumnHeaders(tk.Canvas):
1236
1245
  tf = self.PAR.ops.header_fg
1237
1246
  return tf, redrawn
1238
1247
 
1239
- def redraw_highlight(self, x1, y1, x2, y2, fill, outline, tag):
1248
+ def redraw_highlight(
1249
+ self,
1250
+ x1: float,
1251
+ y1: float,
1252
+ x2: float,
1253
+ y2: float,
1254
+ fill: str,
1255
+ outline: str,
1256
+ tag: str | tuple[str],
1257
+ ) -> bool:
1240
1258
  coords = (x1, y1, x2, y2)
1241
1259
  if self.hidd_high:
1242
1260
  iid, showing = self.hidd_high.popitem()
@@ -1250,7 +1268,13 @@ class ColumnHeaders(tk.Canvas):
1250
1268
  self.disp_high[iid] = True
1251
1269
  return True
1252
1270
 
1253
- def redraw_gridline(self, points, fill, width, tag):
1271
+ def redraw_gridline(
1272
+ self,
1273
+ points: Sequence[float],
1274
+ fill: str,
1275
+ width: int,
1276
+ tag: str | tuple[str],
1277
+ ) -> None:
1254
1278
  if self.hidd_grid:
1255
1279
  t, sh = self.hidd_grid.popitem()
1256
1280
  self.coords(t, points)
@@ -1264,17 +1288,17 @@ class ColumnHeaders(tk.Canvas):
1264
1288
 
1265
1289
  def redraw_dropdown(
1266
1290
  self,
1267
- x1,
1268
- y1,
1269
- x2,
1270
- y2,
1271
- fill,
1272
- outline,
1273
- tag,
1274
- draw_outline=True,
1275
- draw_arrow=True,
1276
- dd_is_open=False,
1277
- ):
1291
+ x1: float,
1292
+ y1: float,
1293
+ x2: float,
1294
+ y2: float,
1295
+ fill: str,
1296
+ outline: str,
1297
+ tag: str | tuple[str],
1298
+ draw_outline: bool = True,
1299
+ draw_arrow: bool = True,
1300
+ dd_is_open: bool = False,
1301
+ ) -> None:
1278
1302
  if draw_outline and self.PAR.ops.show_dropdown_borders:
1279
1303
  self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.PAR.ops.header_fg, tag=tag)
1280
1304
  if draw_arrow:
@@ -1318,7 +1342,17 @@ class ColumnHeaders(tk.Canvas):
1318
1342
  )
1319
1343
  self.disp_dropdown[t] = True
1320
1344
 
1321
- def redraw_checkbox(self, x1, y1, x2, y2, fill, outline, tag, draw_check=False):
1345
+ def redraw_checkbox(
1346
+ self,
1347
+ x1: float,
1348
+ y1: float,
1349
+ x2: float,
1350
+ y2: float,
1351
+ fill: str,
1352
+ outline: str,
1353
+ tag: str | tuple[str],
1354
+ draw_check: bool = False,
1355
+ ) -> None:
1322
1356
  points = rounded_box_coords(x1, y1, x2, y2)
1323
1357
  if self.hidd_checkbox:
1324
1358
  t, sh = self.hidd_checkbox.popitem()
@@ -1362,18 +1396,20 @@ class ColumnHeaders(tk.Canvas):
1362
1396
 
1363
1397
  def redraw_grid_and_text(
1364
1398
  self,
1365
- last_col_line_pos,
1366
- scrollpos_left,
1367
- x_stop,
1368
- start_col,
1369
- end_col,
1370
- scrollpos_right,
1371
- col_pos_exists,
1372
- ):
1399
+ last_col_line_pos: float,
1400
+ scrollpos_left: float,
1401
+ x_stop: float,
1402
+ grid_start_col: int,
1403
+ grid_end_col: int,
1404
+ text_start_col: int,
1405
+ text_end_col: int,
1406
+ scrollpos_right: float,
1407
+ col_pos_exists: bool,
1408
+ ) -> bool:
1373
1409
  try:
1374
1410
  self.configure_scrollregion(last_col_line_pos=last_col_line_pos)
1375
1411
  except Exception:
1376
- return
1412
+ return False
1377
1413
  self.hidd_text.update(self.disp_text)
1378
1414
  self.disp_text = {}
1379
1415
  self.hidd_high.update(self.disp_high)
@@ -1391,7 +1427,7 @@ class ColumnHeaders(tk.Canvas):
1391
1427
  x_stop,
1392
1428
  self.current_height,
1393
1429
  )
1394
- draw_x = self.MT.col_positions[start_col]
1430
+ draw_x = self.MT.col_positions[grid_start_col]
1395
1431
  yend = self.current_height - 5
1396
1432
  if (self.PAR.ops.show_vertical_grid or self.width_resizing_enabled) and col_pos_exists:
1397
1433
  points = [
@@ -1402,7 +1438,7 @@ class ColumnHeaders(tk.Canvas):
1402
1438
  scrollpos_left - 1,
1403
1439
  -1,
1404
1440
  ]
1405
- for c in range(start_col + 1, end_col):
1441
+ for c in range(grid_start_col, grid_end_col):
1406
1442
  draw_x = self.MT.col_positions[c]
1407
1443
  if self.width_resizing_enabled:
1408
1444
  self.visible_col_dividers[c] = (draw_x - 2, 1, draw_x + 2, yend)
@@ -1431,9 +1467,9 @@ class ColumnHeaders(tk.Canvas):
1431
1467
  else color_map[self.PAR.ops.header_selected_columns_bg]
1432
1468
  )
1433
1469
  font = self.PAR.ops.header_font
1434
- selections = self.get_redraw_selections(start_col, end_col)
1470
+ selections = self.get_redraw_selections(text_start_col, grid_end_col)
1435
1471
  dd_coords = self.dropdown.get_coords()
1436
- for c in range(start_col, end_col - 1):
1472
+ for c in range(text_start_col, text_end_col):
1437
1473
  draw_y = self.MT.header_first_ln_ins
1438
1474
  cleftgridln = self.MT.col_positions[c]
1439
1475
  crightgridln = self.MT.col_positions[c + 1]
@@ -1629,7 +1665,7 @@ class ColumnHeaders(tk.Canvas):
1629
1665
  d[box.type_ if box.type_ != "rows" else "cells"].add(c)
1630
1666
  return d
1631
1667
 
1632
- def open_cell(self, event: object = None, ignore_existing_editor=False):
1668
+ def open_cell(self, event: object = None, ignore_existing_editor: bool = False) -> None:
1633
1669
  if not self.MT.anything_selected() or (not ignore_existing_editor and self.text_editor.open):
1634
1670
  return
1635
1671
  if not self.MT.selected:
@@ -1769,14 +1805,19 @@ class ColumnHeaders(tk.Canvas):
1769
1805
  self.text_editor.tktext.bind(key, func)
1770
1806
  return True
1771
1807
 
1772
- # displayed indexes #just here to receive text editor arg
1773
- def text_editor_has_wrapped(self, r=0, c=0, check_lines=None):
1808
+ # displayed indexes
1809
+ def text_editor_has_wrapped(
1810
+ self,
1811
+ r: int = 0,
1812
+ c: int = 0,
1813
+ check_lines: None = None, # just here to receive text editor arg
1814
+ ) -> None:
1774
1815
  if self.width_resizing_enabled:
1775
1816
  curr_width = self.text_editor.window.winfo_width()
1776
1817
  new_width = curr_width + (self.MT.header_txt_height * 2)
1777
1818
  if new_width != curr_width:
1778
1819
  self.text_editor.window.config(width=new_width)
1779
- self.set_col_width_run_binding(c, width=new_width, only_set_if_too_small=False)
1820
+ self.set_col_width_run_binding(c, width=new_width, only_if_too_small=False)
1780
1821
  if self.dropdown.open and self.dropdown.get_coords() == c:
1781
1822
  self.itemconfig(self.dropdown.canvas_id, width=new_width)
1782
1823
  self.dropdown.window.update_idletasks()
@@ -1785,7 +1826,7 @@ class ColumnHeaders(tk.Canvas):
1785
1826
  self.coords(self.text_editor.canvas_id, self.MT.col_positions[c] + 1, 0)
1786
1827
 
1787
1828
  # displayed indexes
1788
- def text_editor_newline_binding(self, event: object = None, check_lines=True):
1829
+ def text_editor_newline_binding(self, event: object = None, check_lines: bool = True) -> None:
1789
1830
  if not self.height_resizing_enabled:
1790
1831
  return
1791
1832
  curr_height = self.text_editor.window.winfo_height()
@@ -1816,7 +1857,7 @@ class ColumnHeaders(tk.Canvas):
1816
1857
  )
1817
1858
  self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
1818
1859
 
1819
- def refresh_open_window_positions(self, zoom: Literal["in", "out"]):
1860
+ def refresh_open_window_positions(self, zoom: Literal["in", "out"]) -> None:
1820
1861
  if self.text_editor.open:
1821
1862
  c = self.text_editor.column
1822
1863
  self.text_editor.window.config(
@@ -1922,7 +1963,11 @@ class ColumnHeaders(tk.Canvas):
1922
1963
  self.focus_set()
1923
1964
  return "break"
1924
1965
 
1925
- def get_dropdown_height_anchor(self, c, text_editor_h=None):
1966
+ def get_dropdown_height_anchor(
1967
+ self,
1968
+ c: int,
1969
+ text_editor_h: None | int = None,
1970
+ ) -> tuple[int, Literal["nw"]]:
1926
1971
  win_h = 5
1927
1972
  datacn = self.MT.datacn(c)
1928
1973
  for i, v in enumerate(self.get_cell_kwargs(datacn, key="dropdown")["values"]):
@@ -1957,7 +2002,7 @@ class ColumnHeaders(tk.Canvas):
1957
2002
  modified_func(event)
1958
2003
  dd_window.search_and_see(event)
1959
2004
 
1960
- def open_dropdown_window(self, c, event: object = None):
2005
+ def open_dropdown_window(self, c: int, event: object = None) -> None:
1961
2006
  self.hide_text_editor("Escape")
1962
2007
  kwargs = self.get_cell_kwargs(self.MT.datacn(c), key="dropdown")
1963
2008
  if kwargs["state"] == "normal":
@@ -2030,7 +2075,12 @@ class ColumnHeaders(tk.Canvas):
2030
2075
  if redraw:
2031
2076
  self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=False, redraw_table=False)
2032
2077
 
2033
- def close_dropdown_window(self, c=None, selection=None, redraw=True):
2078
+ def close_dropdown_window(
2079
+ self,
2080
+ c: None | int = None,
2081
+ selection: object = None,
2082
+ redraw: bool = True,
2083
+ ) -> None:
2034
2084
  if c is not None and selection is not None:
2035
2085
  datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
2036
2086
  kwargs = self.get_cell_kwargs(datacn, key="dropdown")
@@ -2068,7 +2118,7 @@ class ColumnHeaders(tk.Canvas):
2068
2118
  if redraw:
2069
2119
  self.MT.refresh()
2070
2120
 
2071
- def mouseclick_outside_editor_or_dropdown(self, inside: bool = False):
2121
+ def mouseclick_outside_editor_or_dropdown(self, inside: bool = False) -> int | None:
2072
2122
  closed_dd_coords = self.dropdown.get_coords()
2073
2123
  if self.text_editor.open:
2074
2124
  self.close_text_editor(new_tk_event("ButtonPress-1"))
@@ -2082,7 +2132,7 @@ class ColumnHeaders(tk.Canvas):
2082
2132
  )
2083
2133
  return closed_dd_coords
2084
2134
 
2085
- def mouseclick_outside_editor_or_dropdown_all_canvases(self, inside: bool = False):
2135
+ def mouseclick_outside_editor_or_dropdown_all_canvases(self, inside: bool = False) -> int | None:
2086
2136
  self.RI.mouseclick_outside_editor_or_dropdown()
2087
2137
  self.MT.mouseclick_outside_editor_or_dropdown()
2088
2138
  return self.mouseclick_outside_editor_or_dropdown(inside)
@@ -2096,14 +2146,14 @@ class ColumnHeaders(tk.Canvas):
2096
2146
  # internal event use
2097
2147
  def set_cell_data_undo(
2098
2148
  self,
2099
- c=0,
2100
- datacn=None,
2101
- value="",
2102
- cell_resize=True,
2103
- undo=True,
2104
- redraw=True,
2105
- check_input_valid=True,
2106
- ):
2149
+ c: int = 0,
2150
+ datacn: int | None = None,
2151
+ value: object = "",
2152
+ cell_resize: bool = True,
2153
+ undo: bool = True,
2154
+ redraw: bool = True,
2155
+ check_input_valid: bool = True,
2156
+ ) -> bool:
2107
2157
  if datacn is None:
2108
2158
  datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
2109
2159
  event_data = event_dict(
@@ -2134,7 +2184,7 @@ class ColumnHeaders(tk.Canvas):
2134
2184
  self.MT.sheet_modified(event_data)
2135
2185
  return edited
2136
2186
 
2137
- def set_cell_data(self, datacn=None, value=""):
2187
+ def set_cell_data(self, datacn: int | None = None, value: object = "") -> None:
2138
2188
  if isinstance(self.MT._headers, int):
2139
2189
  self.MT.set_cell_data(datarn=self.MT._headers, datacn=datacn, value=value)
2140
2190
  else:
@@ -2156,7 +2206,7 @@ class ColumnHeaders(tk.Canvas):
2156
2206
  return False
2157
2207
  return True
2158
2208
 
2159
- def cell_equal_to(self, datacn, value):
2209
+ def cell_equal_to(self, datacn: int, value: object) -> bool:
2160
2210
  self.fix_header(datacn)
2161
2211
  if isinstance(self.MT._headers, list):
2162
2212
  return self.MT._headers[datacn] == value
@@ -2165,11 +2215,11 @@ class ColumnHeaders(tk.Canvas):
2165
2215
 
2166
2216
  def get_cell_data(
2167
2217
  self,
2168
- datacn,
2169
- get_displayed=False,
2170
- none_to_empty_str=False,
2171
- redirect_int=False,
2172
- ):
2218
+ datacn: int,
2219
+ get_displayed: bool = False,
2220
+ none_to_empty_str: bool = False,
2221
+ redirect_int: bool = False,
2222
+ ) -> object:
2173
2223
  if get_displayed:
2174
2224
  return self.get_valid_cell_data_as_str(datacn, fix=False)
2175
2225
  if redirect_int and isinstance(self.MT._headers, int): # internal use
@@ -2183,7 +2233,7 @@ class ColumnHeaders(tk.Canvas):
2183
2233
  return ""
2184
2234
  return self.MT._headers[datacn]
2185
2235
 
2186
- def get_valid_cell_data_as_str(self, datacn, fix=True) -> str:
2236
+ def get_valid_cell_data_as_str(self, datacn: int, fix: bool = True) -> str:
2187
2237
  kwargs = self.get_cell_kwargs(datacn, key="dropdown")
2188
2238
  if kwargs:
2189
2239
  if kwargs["text"] is not None:
@@ -2204,7 +2254,7 @@ class ColumnHeaders(tk.Canvas):
2204
2254
  value = get_n2a(datacn, self.default_header)
2205
2255
  return value
2206
2256
 
2207
- def get_value_for_empty_cell(self, datacn, c_ops=True):
2257
+ def get_value_for_empty_cell(self, datacn: int, c_ops: bool = True) -> object:
2208
2258
  if self.get_cell_kwargs(datacn, key="checkbox", cell=c_ops):
2209
2259
  return False
2210
2260
  kwargs = self.get_cell_kwargs(datacn, key="dropdown", cell=c_ops)
@@ -2212,10 +2262,10 @@ class ColumnHeaders(tk.Canvas):
2212
2262
  return kwargs["values"][0]
2213
2263
  return ""
2214
2264
 
2215
- def get_empty_header_seq(self, end, start=0, c_ops=True):
2265
+ def get_empty_header_seq(self, end: int, start: int = 0, c_ops: bool = True) -> list[object]:
2216
2266
  return [self.get_value_for_empty_cell(datacn, c_ops=c_ops) for datacn in range(start, end)]
2217
2267
 
2218
- def fix_header(self, datacn=None, fix_values=tuple()):
2268
+ def fix_header(self, datacn: None | int = None) -> None:
2219
2269
  if isinstance(self.MT._headers, int):
2220
2270
  return
2221
2271
  if isinstance(self.MT._headers, float):
@@ -2228,15 +2278,11 @@ class ColumnHeaders(tk.Canvas):
2228
2278
  self.MT._headers = []
2229
2279
  if isinstance(datacn, int) and datacn >= len(self.MT._headers):
2230
2280
  self.MT._headers.extend(self.get_empty_header_seq(end=datacn + 1, start=len(self.MT._headers)))
2231
- if fix_values:
2232
- for cn, v in enumerate(islice(self.MT._headers, fix_values[0], fix_values[1])):
2233
- if not self.input_valid_for_cell(cn, v):
2234
- self.MT._headers[cn] = self.get_value_for_empty_cell(cn)
2235
2281
 
2236
2282
  # displayed indexes
2237
- def set_col_width_run_binding(self, c, width=None, only_set_if_too_small=True):
2283
+ def set_col_width_run_binding(self, c: int, width: int | None = None, only_if_too_small: bool = True) -> None:
2238
2284
  old_width = self.MT.col_positions[c + 1] - self.MT.col_positions[c]
2239
- new_width = self.set_col_width(c, width=width, only_set_if_too_small=only_set_if_too_small)
2285
+ new_width = self.set_col_width(c, width=width, only_if_too_small=only_if_too_small)
2240
2286
  if self.column_width_resize_func is not None and old_width != new_width:
2241
2287
  self.column_width_resize_func(
2242
2288
  event_dict(
@@ -2247,7 +2293,7 @@ class ColumnHeaders(tk.Canvas):
2247
2293
  )
2248
2294
 
2249
2295
  # internal event use
2250
- def click_checkbox(self, c, datacn=None, undo=True, redraw=True):
2296
+ def click_checkbox(self, c: int, datacn: int | None = None, undo: bool = True, redraw: bool = True) -> None:
2251
2297
  if datacn is None:
2252
2298
  datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
2253
2299
  kwargs = self.get_cell_kwargs(datacn, key="checkbox")
@@ -2282,7 +2328,7 @@ class ColumnHeaders(tk.Canvas):
2282
2328
  if redraw:
2283
2329
  self.MT.refresh()
2284
2330
 
2285
- def get_cell_kwargs(self, datacn, key="dropdown", cell=True):
2331
+ def get_cell_kwargs(self, datacn: int, key: Hashable = "dropdown", cell: bool = True) -> dict:
2286
2332
  if cell and datacn in self.cell_options and key in self.cell_options[datacn]:
2287
2333
  return self.cell_options[datacn][key]
2288
2334
  return {}