tksheet 7.2.0__py3-none-any.whl → 7.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tksheet/__init__.py +1 -1
- tksheet/column_headers.py +273 -212
- tksheet/main_table.py +87 -71
- tksheet/row_index.py +247 -200
- tksheet/sheet.py +97 -48
- tksheet/top_left_rectangle.py +7 -2
- {tksheet-7.2.0.dist-info → tksheet-7.2.2.dist-info}/METADATA +6 -4
- tksheet-7.2.2.dist-info/RECORD +20 -0
- tksheet-7.2.0.dist-info/RECORD +0 -20
- {tksheet-7.2.0.dist-info → tksheet-7.2.2.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.2.0.dist-info → tksheet-7.2.2.dist-info}/WHEEL +0 -0
- {tksheet-7.2.0.dist-info → tksheet-7.2.2.dist-info}/top_level.txt +0 -0
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
|
-
|
165
|
-
|
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
|
-
|
176
|
-
|
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()
|
@@ -903,12 +912,13 @@ class ColumnHeaders(tk.Canvas):
|
|
903
912
|
|
904
913
|
def toggle_select_col(
|
905
914
|
self,
|
906
|
-
column,
|
907
|
-
add_selection=True,
|
908
|
-
redraw=True,
|
909
|
-
run_binding_func=True,
|
910
|
-
set_as_current=True,
|
911
|
-
|
915
|
+
column: int,
|
916
|
+
add_selection: bool = True,
|
917
|
+
redraw: bool = True,
|
918
|
+
run_binding_func: bool = True,
|
919
|
+
set_as_current: bool = True,
|
920
|
+
ext: bool = False,
|
921
|
+
) -> int:
|
912
922
|
if add_selection:
|
913
923
|
if self.MT.col_selected(column):
|
914
924
|
fill_iid = self.MT.deselect(c=column, redraw=redraw)
|
@@ -918,26 +928,40 @@ class ColumnHeaders(tk.Canvas):
|
|
918
928
|
redraw=redraw,
|
919
929
|
run_binding_func=run_binding_func,
|
920
930
|
set_as_current=set_as_current,
|
931
|
+
ext=ext,
|
921
932
|
)
|
922
933
|
else:
|
923
934
|
if self.MT.col_selected(column):
|
924
935
|
fill_iid = self.MT.deselect(c=column, redraw=redraw)
|
925
936
|
else:
|
926
|
-
fill_iid = self.select_col(column, redraw=redraw)
|
937
|
+
fill_iid = self.select_col(column, redraw=redraw, ext=ext)
|
927
938
|
return fill_iid
|
928
939
|
|
929
|
-
def select_col(
|
940
|
+
def select_col(
|
941
|
+
self,
|
942
|
+
c: int,
|
943
|
+
redraw: bool = False,
|
944
|
+
run_binding_func: bool = True,
|
945
|
+
ext: bool = False,
|
946
|
+
) -> int:
|
930
947
|
self.MT.deselect("all", redraw=False)
|
931
|
-
fill_iid = self.MT.create_selection_box(0, c, len(self.MT.row_positions) - 1, c + 1, "columns")
|
948
|
+
fill_iid = self.MT.create_selection_box(0, c, len(self.MT.row_positions) - 1, c + 1, "columns", ext=ext)
|
932
949
|
if redraw:
|
933
950
|
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
934
951
|
if run_binding_func:
|
935
952
|
self.MT.run_selection_binding("columns")
|
936
953
|
return fill_iid
|
937
954
|
|
938
|
-
def add_selection(
|
955
|
+
def add_selection(
|
956
|
+
self,
|
957
|
+
c: int,
|
958
|
+
redraw: bool = False,
|
959
|
+
run_binding_func: bool = True,
|
960
|
+
set_as_current: bool = True,
|
961
|
+
ext: bool = False,
|
962
|
+
) -> int:
|
939
963
|
box = (0, c, len(self.MT.row_positions) - 1, c + 1, "columns")
|
940
|
-
fill_iid = self.MT.create_selection_box(*box, set_current=set_as_current)
|
964
|
+
fill_iid = self.MT.create_selection_box(*box, set_current=set_as_current, ext=ext)
|
941
965
|
if redraw:
|
942
966
|
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
943
967
|
if run_binding_func:
|
@@ -982,7 +1006,7 @@ class ColumnHeaders(tk.Canvas):
|
|
982
1006
|
self.hidd_boxes.add(item)
|
983
1007
|
self.itemconfig(item, state="hidden")
|
984
1008
|
|
985
|
-
def get_cell_dimensions(self, datacn):
|
1009
|
+
def get_cell_dimensions(self, datacn: int) -> tuple[int, int]:
|
986
1010
|
txt = self.get_valid_cell_data_as_str(datacn, fix=False)
|
987
1011
|
if txt:
|
988
1012
|
self.MT.txt_measure_canvas.itemconfig(
|
@@ -1000,29 +1024,28 @@ class ColumnHeaders(tk.Canvas):
|
|
1000
1024
|
return w + self.MT.header_txt_height, h
|
1001
1025
|
return w, h
|
1002
1026
|
|
1003
|
-
def set_height_of_header_to_text(
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
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)
|
1010
1035
|
):
|
1011
|
-
return
|
1036
|
+
return h
|
1037
|
+
self.fix_header()
|
1012
1038
|
qconf = self.MT.txt_measure_canvas.itemconfig
|
1013
1039
|
qbbox = self.MT.txt_measure_canvas.bbox
|
1014
1040
|
qtxtm = self.MT.txt_measure_canvas_text
|
1015
1041
|
qfont = self.PAR.ops.header_font
|
1016
|
-
new_height = self.MT.min_header_height
|
1017
1042
|
default_header_height = self.MT.get_default_header_height()
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
new_height = h
|
1025
|
-
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:
|
1026
1049
|
if self.MT.all_columns_displayed:
|
1027
1050
|
if isinstance(self.MT._headers, list):
|
1028
1051
|
iterable = range(len(self.MT._headers))
|
@@ -1030,141 +1053,142 @@ class ColumnHeaders(tk.Canvas):
|
|
1030
1053
|
iterable = range(len(self.MT.data[self.MT._headers]))
|
1031
1054
|
else:
|
1032
1055
|
iterable = self.MT.displayed_columns
|
1033
|
-
if
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
elif h > self.MT.max_header_height:
|
1039
|
-
h = int(self.MT.max_header_height)
|
1040
|
-
if h > new_height:
|
1041
|
-
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
|
1042
1061
|
elif isinstance(self.MT._headers, int):
|
1043
1062
|
datarn = self.MT._headers
|
1044
1063
|
for datacn in iterable:
|
1045
|
-
txt
|
1046
|
-
if txt:
|
1064
|
+
if txt := self.MT.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True):
|
1047
1065
|
qconf(qtxtm, text=txt, font=qfont)
|
1048
1066
|
b = qbbox(qtxtm)
|
1049
|
-
|
1067
|
+
th = b[3] - b[1] + 5
|
1050
1068
|
else:
|
1051
|
-
|
1052
|
-
if
|
1053
|
-
h =
|
1054
|
-
elif h > self.MT.max_header_height:
|
1055
|
-
h = int(self.MT.max_header_height)
|
1056
|
-
if h > new_height:
|
1057
|
-
new_height = h
|
1069
|
+
th = default_header_height
|
1070
|
+
if th > h:
|
1071
|
+
h = th
|
1058
1072
|
space_bot = self.MT.get_space_bot(0)
|
1059
|
-
if
|
1060
|
-
|
1061
|
-
if
|
1062
|
-
self.
|
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)
|
1063
1081
|
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
1064
|
-
return
|
1082
|
+
return h
|
1065
1083
|
|
1066
|
-
def
|
1084
|
+
def get_col_text_width(
|
1067
1085
|
self,
|
1068
|
-
col,
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
recreate=True,
|
1073
|
-
return_new_width=False,
|
1074
|
-
):
|
1075
|
-
if col < 0:
|
1076
|
-
return
|
1077
|
-
qconf = self.MT.txt_measure_canvas.itemconfig
|
1078
|
-
qbbox = self.MT.txt_measure_canvas.bbox
|
1079
|
-
qtxtm = self.MT.txt_measure_canvas_text
|
1080
|
-
qtxth = self.MT.table_txt_height
|
1081
|
-
qfont = self.PAR.ops.table_font
|
1086
|
+
col: int,
|
1087
|
+
visible_only: bool = False,
|
1088
|
+
only_if_too_small: bool = False,
|
1089
|
+
) -> int:
|
1082
1090
|
self.fix_header()
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
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:
|
1086
1097
|
if self.MT.all_rows_displayed:
|
1087
|
-
if
|
1088
|
-
|
1089
|
-
start_row, end_row = self.MT.get_visible_rows(y1, y2)
|
1098
|
+
if visible_only:
|
1099
|
+
iterable = range(*self.MT.visible_text_rows)
|
1090
1100
|
else:
|
1091
|
-
|
1092
|
-
iterable = range(start_row, end_row)
|
1101
|
+
iterable = range(0, len(self.MT.data))
|
1093
1102
|
else:
|
1094
|
-
if
|
1095
|
-
|
1096
|
-
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
|
1097
1105
|
else:
|
1098
1106
|
start_row, end_row = 0, len(self.MT.displayed_rows)
|
1099
1107
|
iterable = self.MT.displayed_rows[start_row:end_row]
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
self.MT.
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
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
|
1133
|
+
|
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
|
1141
1159
|
|
1142
|
-
def set_width_of_all_cols(
|
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:
|
1143
1166
|
if width is None:
|
1144
1167
|
if self.MT.all_columns_displayed:
|
1145
1168
|
iterable = range(self.MT.total_data_cols())
|
1146
1169
|
else:
|
1147
1170
|
iterable = range(len(self.MT.displayed_columns))
|
1148
1171
|
self.MT.set_col_positions(
|
1149
|
-
itr=(
|
1150
|
-
self.set_col_width(
|
1151
|
-
cn,
|
1152
|
-
only_set_if_too_small=only_set_if_too_small,
|
1153
|
-
recreate=False,
|
1154
|
-
return_new_width=True,
|
1155
|
-
)
|
1156
|
-
for cn in iterable
|
1157
|
-
)
|
1172
|
+
itr=(self.get_col_text_width(cn, only_if_too_small=only_if_too_small) for cn in iterable)
|
1158
1173
|
)
|
1159
1174
|
elif width is not None:
|
1160
1175
|
if self.MT.all_columns_displayed:
|
1161
|
-
self.MT.set_col_positions(itr=(width
|
1176
|
+
self.MT.set_col_positions(itr=repeat(width, self.MT.total_data_cols()))
|
1162
1177
|
else:
|
1163
|
-
self.MT.set_col_positions(itr=(width
|
1178
|
+
self.MT.set_col_positions(itr=repeat(width, len(self.MT.displayed_columns)))
|
1164
1179
|
if recreate:
|
1165
1180
|
self.MT.recreate_all_selection_boxes()
|
1166
1181
|
|
1167
|
-
def redraw_highlight_get_text_fg(
|
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]:
|
1168
1192
|
redrawn = False
|
1169
1193
|
kwargs = self.get_cell_kwargs(datacn, key="highlight")
|
1170
1194
|
if kwargs:
|
@@ -1221,7 +1245,16 @@ class ColumnHeaders(tk.Canvas):
|
|
1221
1245
|
tf = self.PAR.ops.header_fg
|
1222
1246
|
return tf, redrawn
|
1223
1247
|
|
1224
|
-
def redraw_highlight(
|
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:
|
1225
1258
|
coords = (x1, y1, x2, y2)
|
1226
1259
|
if self.hidd_high:
|
1227
1260
|
iid, showing = self.hidd_high.popitem()
|
@@ -1235,7 +1268,13 @@ class ColumnHeaders(tk.Canvas):
|
|
1235
1268
|
self.disp_high[iid] = True
|
1236
1269
|
return True
|
1237
1270
|
|
1238
|
-
def redraw_gridline(
|
1271
|
+
def redraw_gridline(
|
1272
|
+
self,
|
1273
|
+
points: Sequence[float],
|
1274
|
+
fill: str,
|
1275
|
+
width: int,
|
1276
|
+
tag: str | tuple[str],
|
1277
|
+
) -> None:
|
1239
1278
|
if self.hidd_grid:
|
1240
1279
|
t, sh = self.hidd_grid.popitem()
|
1241
1280
|
self.coords(t, points)
|
@@ -1249,17 +1288,17 @@ class ColumnHeaders(tk.Canvas):
|
|
1249
1288
|
|
1250
1289
|
def redraw_dropdown(
|
1251
1290
|
self,
|
1252
|
-
x1,
|
1253
|
-
y1,
|
1254
|
-
x2,
|
1255
|
-
y2,
|
1256
|
-
fill,
|
1257
|
-
outline,
|
1258
|
-
tag,
|
1259
|
-
draw_outline=True,
|
1260
|
-
draw_arrow=True,
|
1261
|
-
dd_is_open=False,
|
1262
|
-
):
|
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:
|
1263
1302
|
if draw_outline and self.PAR.ops.show_dropdown_borders:
|
1264
1303
|
self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.PAR.ops.header_fg, tag=tag)
|
1265
1304
|
if draw_arrow:
|
@@ -1303,7 +1342,17 @@ class ColumnHeaders(tk.Canvas):
|
|
1303
1342
|
)
|
1304
1343
|
self.disp_dropdown[t] = True
|
1305
1344
|
|
1306
|
-
def redraw_checkbox(
|
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:
|
1307
1356
|
points = rounded_box_coords(x1, y1, x2, y2)
|
1308
1357
|
if self.hidd_checkbox:
|
1309
1358
|
t, sh = self.hidd_checkbox.popitem()
|
@@ -1347,18 +1396,20 @@ class ColumnHeaders(tk.Canvas):
|
|
1347
1396
|
|
1348
1397
|
def redraw_grid_and_text(
|
1349
1398
|
self,
|
1350
|
-
last_col_line_pos,
|
1351
|
-
scrollpos_left,
|
1352
|
-
x_stop,
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
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:
|
1358
1409
|
try:
|
1359
1410
|
self.configure_scrollregion(last_col_line_pos=last_col_line_pos)
|
1360
1411
|
except Exception:
|
1361
|
-
return
|
1412
|
+
return False
|
1362
1413
|
self.hidd_text.update(self.disp_text)
|
1363
1414
|
self.disp_text = {}
|
1364
1415
|
self.hidd_high.update(self.disp_high)
|
@@ -1376,7 +1427,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1376
1427
|
x_stop,
|
1377
1428
|
self.current_height,
|
1378
1429
|
)
|
1379
|
-
draw_x = self.MT.col_positions[
|
1430
|
+
draw_x = self.MT.col_positions[grid_start_col]
|
1380
1431
|
yend = self.current_height - 5
|
1381
1432
|
if (self.PAR.ops.show_vertical_grid or self.width_resizing_enabled) and col_pos_exists:
|
1382
1433
|
points = [
|
@@ -1387,7 +1438,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1387
1438
|
scrollpos_left - 1,
|
1388
1439
|
-1,
|
1389
1440
|
]
|
1390
|
-
for c in range(
|
1441
|
+
for c in range(grid_start_col, grid_end_col):
|
1391
1442
|
draw_x = self.MT.col_positions[c]
|
1392
1443
|
if self.width_resizing_enabled:
|
1393
1444
|
self.visible_col_dividers[c] = (draw_x - 2, 1, draw_x + 2, yend)
|
@@ -1416,9 +1467,9 @@ class ColumnHeaders(tk.Canvas):
|
|
1416
1467
|
else color_map[self.PAR.ops.header_selected_columns_bg]
|
1417
1468
|
)
|
1418
1469
|
font = self.PAR.ops.header_font
|
1419
|
-
selections = self.get_redraw_selections(
|
1470
|
+
selections = self.get_redraw_selections(text_start_col, grid_end_col)
|
1420
1471
|
dd_coords = self.dropdown.get_coords()
|
1421
|
-
for c in range(
|
1472
|
+
for c in range(text_start_col, text_end_col):
|
1422
1473
|
draw_y = self.MT.header_first_ln_ins
|
1423
1474
|
cleftgridln = self.MT.col_positions[c]
|
1424
1475
|
crightgridln = self.MT.col_positions[c + 1]
|
@@ -1614,7 +1665,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1614
1665
|
d[box.type_ if box.type_ != "rows" else "cells"].add(c)
|
1615
1666
|
return d
|
1616
1667
|
|
1617
|
-
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:
|
1618
1669
|
if not self.MT.anything_selected() or (not ignore_existing_editor and self.text_editor.open):
|
1619
1670
|
return
|
1620
1671
|
if not self.MT.selected:
|
@@ -1754,14 +1805,19 @@ class ColumnHeaders(tk.Canvas):
|
|
1754
1805
|
self.text_editor.tktext.bind(key, func)
|
1755
1806
|
return True
|
1756
1807
|
|
1757
|
-
# displayed indexes
|
1758
|
-
def text_editor_has_wrapped(
|
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:
|
1759
1815
|
if self.width_resizing_enabled:
|
1760
1816
|
curr_width = self.text_editor.window.winfo_width()
|
1761
1817
|
new_width = curr_width + (self.MT.header_txt_height * 2)
|
1762
1818
|
if new_width != curr_width:
|
1763
1819
|
self.text_editor.window.config(width=new_width)
|
1764
|
-
self.set_col_width_run_binding(c, width=new_width,
|
1820
|
+
self.set_col_width_run_binding(c, width=new_width, only_if_too_small=False)
|
1765
1821
|
if self.dropdown.open and self.dropdown.get_coords() == c:
|
1766
1822
|
self.itemconfig(self.dropdown.canvas_id, width=new_width)
|
1767
1823
|
self.dropdown.window.update_idletasks()
|
@@ -1770,7 +1826,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1770
1826
|
self.coords(self.text_editor.canvas_id, self.MT.col_positions[c] + 1, 0)
|
1771
1827
|
|
1772
1828
|
# displayed indexes
|
1773
|
-
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:
|
1774
1830
|
if not self.height_resizing_enabled:
|
1775
1831
|
return
|
1776
1832
|
curr_height = self.text_editor.window.winfo_height()
|
@@ -1801,7 +1857,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1801
1857
|
)
|
1802
1858
|
self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
|
1803
1859
|
|
1804
|
-
def refresh_open_window_positions(self, zoom: Literal["in", "out"]):
|
1860
|
+
def refresh_open_window_positions(self, zoom: Literal["in", "out"]) -> None:
|
1805
1861
|
if self.text_editor.open:
|
1806
1862
|
c = self.text_editor.column
|
1807
1863
|
self.text_editor.window.config(
|
@@ -1907,7 +1963,11 @@ class ColumnHeaders(tk.Canvas):
|
|
1907
1963
|
self.focus_set()
|
1908
1964
|
return "break"
|
1909
1965
|
|
1910
|
-
def get_dropdown_height_anchor(
|
1966
|
+
def get_dropdown_height_anchor(
|
1967
|
+
self,
|
1968
|
+
c: int,
|
1969
|
+
text_editor_h: None | int = None,
|
1970
|
+
) -> tuple[int, Literal["nw"]]:
|
1911
1971
|
win_h = 5
|
1912
1972
|
datacn = self.MT.datacn(c)
|
1913
1973
|
for i, v in enumerate(self.get_cell_kwargs(datacn, key="dropdown")["values"]):
|
@@ -1942,7 +2002,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1942
2002
|
modified_func(event)
|
1943
2003
|
dd_window.search_and_see(event)
|
1944
2004
|
|
1945
|
-
def open_dropdown_window(self, c, event: object = None):
|
2005
|
+
def open_dropdown_window(self, c: int, event: object = None) -> None:
|
1946
2006
|
self.hide_text_editor("Escape")
|
1947
2007
|
kwargs = self.get_cell_kwargs(self.MT.datacn(c), key="dropdown")
|
1948
2008
|
if kwargs["state"] == "normal":
|
@@ -2015,7 +2075,12 @@ class ColumnHeaders(tk.Canvas):
|
|
2015
2075
|
if redraw:
|
2016
2076
|
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=False, redraw_table=False)
|
2017
2077
|
|
2018
|
-
def close_dropdown_window(
|
2078
|
+
def close_dropdown_window(
|
2079
|
+
self,
|
2080
|
+
c: None | int = None,
|
2081
|
+
selection: object = None,
|
2082
|
+
redraw: bool = True,
|
2083
|
+
) -> None:
|
2019
2084
|
if c is not None and selection is not None:
|
2020
2085
|
datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
|
2021
2086
|
kwargs = self.get_cell_kwargs(datacn, key="dropdown")
|
@@ -2053,7 +2118,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2053
2118
|
if redraw:
|
2054
2119
|
self.MT.refresh()
|
2055
2120
|
|
2056
|
-
def mouseclick_outside_editor_or_dropdown(self, inside: bool = False):
|
2121
|
+
def mouseclick_outside_editor_or_dropdown(self, inside: bool = False) -> int | None:
|
2057
2122
|
closed_dd_coords = self.dropdown.get_coords()
|
2058
2123
|
if self.text_editor.open:
|
2059
2124
|
self.close_text_editor(new_tk_event("ButtonPress-1"))
|
@@ -2067,7 +2132,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2067
2132
|
)
|
2068
2133
|
return closed_dd_coords
|
2069
2134
|
|
2070
|
-
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:
|
2071
2136
|
self.RI.mouseclick_outside_editor_or_dropdown()
|
2072
2137
|
self.MT.mouseclick_outside_editor_or_dropdown()
|
2073
2138
|
return self.mouseclick_outside_editor_or_dropdown(inside)
|
@@ -2081,14 +2146,14 @@ class ColumnHeaders(tk.Canvas):
|
|
2081
2146
|
# internal event use
|
2082
2147
|
def set_cell_data_undo(
|
2083
2148
|
self,
|
2084
|
-
c=0,
|
2085
|
-
datacn=None,
|
2086
|
-
value="",
|
2087
|
-
cell_resize=True,
|
2088
|
-
undo=True,
|
2089
|
-
redraw=True,
|
2090
|
-
check_input_valid=True,
|
2091
|
-
):
|
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:
|
2092
2157
|
if datacn is None:
|
2093
2158
|
datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
|
2094
2159
|
event_data = event_dict(
|
@@ -2119,7 +2184,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2119
2184
|
self.MT.sheet_modified(event_data)
|
2120
2185
|
return edited
|
2121
2186
|
|
2122
|
-
def set_cell_data(self, datacn=None, value=""):
|
2187
|
+
def set_cell_data(self, datacn: int | None = None, value: object = "") -> None:
|
2123
2188
|
if isinstance(self.MT._headers, int):
|
2124
2189
|
self.MT.set_cell_data(datarn=self.MT._headers, datacn=datacn, value=value)
|
2125
2190
|
else:
|
@@ -2141,7 +2206,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2141
2206
|
return False
|
2142
2207
|
return True
|
2143
2208
|
|
2144
|
-
def cell_equal_to(self, datacn, value):
|
2209
|
+
def cell_equal_to(self, datacn: int, value: object) -> bool:
|
2145
2210
|
self.fix_header(datacn)
|
2146
2211
|
if isinstance(self.MT._headers, list):
|
2147
2212
|
return self.MT._headers[datacn] == value
|
@@ -2150,11 +2215,11 @@ class ColumnHeaders(tk.Canvas):
|
|
2150
2215
|
|
2151
2216
|
def get_cell_data(
|
2152
2217
|
self,
|
2153
|
-
datacn,
|
2154
|
-
get_displayed=False,
|
2155
|
-
none_to_empty_str=False,
|
2156
|
-
redirect_int=False,
|
2157
|
-
):
|
2218
|
+
datacn: int,
|
2219
|
+
get_displayed: bool = False,
|
2220
|
+
none_to_empty_str: bool = False,
|
2221
|
+
redirect_int: bool = False,
|
2222
|
+
) -> object:
|
2158
2223
|
if get_displayed:
|
2159
2224
|
return self.get_valid_cell_data_as_str(datacn, fix=False)
|
2160
2225
|
if redirect_int and isinstance(self.MT._headers, int): # internal use
|
@@ -2168,7 +2233,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2168
2233
|
return ""
|
2169
2234
|
return self.MT._headers[datacn]
|
2170
2235
|
|
2171
|
-
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:
|
2172
2237
|
kwargs = self.get_cell_kwargs(datacn, key="dropdown")
|
2173
2238
|
if kwargs:
|
2174
2239
|
if kwargs["text"] is not None:
|
@@ -2189,7 +2254,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2189
2254
|
value = get_n2a(datacn, self.default_header)
|
2190
2255
|
return value
|
2191
2256
|
|
2192
|
-
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:
|
2193
2258
|
if self.get_cell_kwargs(datacn, key="checkbox", cell=c_ops):
|
2194
2259
|
return False
|
2195
2260
|
kwargs = self.get_cell_kwargs(datacn, key="dropdown", cell=c_ops)
|
@@ -2197,10 +2262,10 @@ class ColumnHeaders(tk.Canvas):
|
|
2197
2262
|
return kwargs["values"][0]
|
2198
2263
|
return ""
|
2199
2264
|
|
2200
|
-
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]:
|
2201
2266
|
return [self.get_value_for_empty_cell(datacn, c_ops=c_ops) for datacn in range(start, end)]
|
2202
2267
|
|
2203
|
-
def fix_header(self, datacn
|
2268
|
+
def fix_header(self, datacn: None | int = None) -> None:
|
2204
2269
|
if isinstance(self.MT._headers, int):
|
2205
2270
|
return
|
2206
2271
|
if isinstance(self.MT._headers, float):
|
@@ -2213,15 +2278,11 @@ class ColumnHeaders(tk.Canvas):
|
|
2213
2278
|
self.MT._headers = []
|
2214
2279
|
if isinstance(datacn, int) and datacn >= len(self.MT._headers):
|
2215
2280
|
self.MT._headers.extend(self.get_empty_header_seq(end=datacn + 1, start=len(self.MT._headers)))
|
2216
|
-
if fix_values:
|
2217
|
-
for cn, v in enumerate(islice(self.MT._headers, fix_values[0], fix_values[1])):
|
2218
|
-
if not self.input_valid_for_cell(cn, v):
|
2219
|
-
self.MT._headers[cn] = self.get_value_for_empty_cell(cn)
|
2220
2281
|
|
2221
2282
|
# displayed indexes
|
2222
|
-
def set_col_width_run_binding(self, c, width=None,
|
2283
|
+
def set_col_width_run_binding(self, c: int, width: int | None = None, only_if_too_small: bool = True) -> None:
|
2223
2284
|
old_width = self.MT.col_positions[c + 1] - self.MT.col_positions[c]
|
2224
|
-
new_width = self.set_col_width(c, width=width,
|
2285
|
+
new_width = self.set_col_width(c, width=width, only_if_too_small=only_if_too_small)
|
2225
2286
|
if self.column_width_resize_func is not None and old_width != new_width:
|
2226
2287
|
self.column_width_resize_func(
|
2227
2288
|
event_dict(
|
@@ -2232,7 +2293,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2232
2293
|
)
|
2233
2294
|
|
2234
2295
|
# internal event use
|
2235
|
-
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:
|
2236
2297
|
if datacn is None:
|
2237
2298
|
datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
|
2238
2299
|
kwargs = self.get_cell_kwargs(datacn, key="checkbox")
|
@@ -2267,7 +2328,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2267
2328
|
if redraw:
|
2268
2329
|
self.MT.refresh()
|
2269
2330
|
|
2270
|
-
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:
|
2271
2332
|
if cell and datacn in self.cell_options and key in self.cell_options[datacn]:
|
2272
2333
|
return self.cell_options[datacn][key]
|
2273
2334
|
return {}
|