tksheet 7.3.3__py3-none-any.whl → 7.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tksheet/__init__.py +11 -11
- tksheet/colors.py +1 -1
- tksheet/column_headers.py +397 -366
- tksheet/constants.py +13 -0
- tksheet/find_window.py +4 -13
- tksheet/functions.py +198 -37
- tksheet/main_table.py +1109 -848
- tksheet/other_classes.py +13 -9
- tksheet/row_index.py +939 -437
- tksheet/sheet.py +470 -619
- tksheet/sheet_options.py +47 -12
- tksheet/sorting.py +369 -0
- tksheet/text_editor.py +4 -15
- tksheet/{types.py → tksheet_types.py} +12 -8
- {tksheet-7.3.3.dist-info → tksheet-7.4.0.dist-info}/METADATA +14 -14
- tksheet-7.4.0.dist-info/RECORD +22 -0
- tksheet-7.3.3.dist-info/RECORD +0 -21
- {tksheet-7.3.3.dist-info → tksheet-7.4.0.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.3.3.dist-info → tksheet-7.4.0.dist-info}/WHEEL +0 -0
- {tksheet-7.3.3.dist-info → tksheet-7.4.0.dist-info}/top_level.txt +0 -0
tksheet/main_table.py
CHANGED
@@ -3,58 +3,34 @@ 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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
from
|
11
|
-
|
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
|
-
|
41
|
-
)
|
16
|
+
from .colors import color_map
|
17
|
+
from .column_headers import ColumnHeaders
|
42
18
|
from .constants import (
|
43
19
|
USER_OS,
|
20
|
+
_test_str,
|
44
21
|
bind_add_columns,
|
45
22
|
bind_add_rows,
|
46
23
|
bind_del_columns,
|
47
24
|
bind_del_rows,
|
48
25
|
ctrl_key,
|
26
|
+
font_value_error,
|
49
27
|
rc_binding,
|
50
28
|
text_editor_close_bindings,
|
51
29
|
text_editor_newline_bindings,
|
52
30
|
text_editor_to_unbind,
|
53
31
|
val_modifying_options,
|
54
32
|
)
|
55
|
-
from .find_window import
|
56
|
-
FindWindow,
|
57
|
-
)
|
33
|
+
from .find_window import FindWindow
|
58
34
|
from .formatters import (
|
59
35
|
data_to_str,
|
60
36
|
format_data,
|
@@ -72,6 +48,7 @@ from .functions import (
|
|
72
48
|
cell_right_within_box,
|
73
49
|
color_tup,
|
74
50
|
consecutive_ranges,
|
51
|
+
data_to_displayed_idxs,
|
75
52
|
diff_gen,
|
76
53
|
diff_list,
|
77
54
|
down_cell_within_box,
|
@@ -97,11 +74,13 @@ from .functions import (
|
|
97
74
|
move_elements_by_mapping,
|
98
75
|
new_tk_event,
|
99
76
|
next_cell,
|
77
|
+
push_n,
|
100
78
|
rounded_box_coords,
|
101
79
|
span_idxs_post_move,
|
102
80
|
stored_event_dict,
|
103
81
|
try_binding,
|
104
82
|
unpickle_obj,
|
83
|
+
wrap_text,
|
105
84
|
)
|
106
85
|
from .other_classes import (
|
107
86
|
Box_nt,
|
@@ -119,24 +98,30 @@ from .other_classes import (
|
|
119
98
|
SelectionBox,
|
120
99
|
TextEditorStorage,
|
121
100
|
)
|
122
|
-
from .
|
123
|
-
|
124
|
-
|
125
|
-
from .
|
126
|
-
AnyIter,
|
127
|
-
)
|
101
|
+
from .row_index import RowIndex
|
102
|
+
from .sorting import sort_selection
|
103
|
+
from .text_editor import TextEditor
|
104
|
+
from .tksheet_types import AnyIter
|
128
105
|
|
129
106
|
|
130
107
|
class MainTable(tk.Canvas):
|
131
|
-
def __init__(
|
108
|
+
def __init__(
|
109
|
+
self,
|
110
|
+
parent,
|
111
|
+
row_index_canvas: RowIndex,
|
112
|
+
column_headers_canvas: ColumnHeaders,
|
113
|
+
**kwargs,
|
114
|
+
):
|
132
115
|
super().__init__(
|
133
|
-
|
134
|
-
background=
|
116
|
+
parent,
|
117
|
+
background=parent.ops.table_bg,
|
135
118
|
highlightthickness=0,
|
136
119
|
)
|
137
|
-
self.PAR =
|
120
|
+
self.PAR = parent
|
138
121
|
self.PAR_width = 0
|
139
122
|
self.PAR_height = 0
|
123
|
+
self.cells_cache = None
|
124
|
+
self.table_txt_height, self.index_txt_height, self.header_txt_height = 0, 0, 0
|
140
125
|
self.scrollregion = tuple()
|
141
126
|
self.current_cursor = ""
|
142
127
|
self.ctrl_b1_pressed = False
|
@@ -207,6 +192,9 @@ class MainTable(tk.Canvas):
|
|
207
192
|
|
208
193
|
self.edit_validation_func = None
|
209
194
|
|
195
|
+
self.extra_begin_sort_cells_func = None
|
196
|
+
self.extra_end_sort_cells_func = None
|
197
|
+
|
210
198
|
self.extra_begin_ctrl_c_func = None
|
211
199
|
self.extra_end_ctrl_c_func = None
|
212
200
|
|
@@ -270,14 +258,19 @@ class MainTable(tk.Canvas):
|
|
270
258
|
self.rc_insert_column_enabled = False
|
271
259
|
self.rc_delete_row_enabled = False
|
272
260
|
self.rc_insert_row_enabled = False
|
261
|
+
self.rc_sort_cells_enabled = False
|
262
|
+
self.rc_sort_row_enabled = False
|
263
|
+
self.rc_sort_column_enabled = False
|
264
|
+
self.rc_sort_rows_enabled = False
|
265
|
+
self.rc_sort_columns_enabled = False
|
273
266
|
self.rc_popup_menus_enabled = False
|
274
267
|
self.edit_cell_enabled = False
|
275
|
-
self.CH =
|
268
|
+
self.CH = column_headers_canvas
|
276
269
|
self.CH.MT = self
|
277
|
-
self.CH.RI =
|
278
|
-
self.RI =
|
270
|
+
self.CH.RI = row_index_canvas
|
271
|
+
self.RI = row_index_canvas
|
279
272
|
self.RI.MT = self
|
280
|
-
self.RI.CH =
|
273
|
+
self.RI.CH = column_headers_canvas
|
281
274
|
self.TL = None # is set from within TopLeftRectangle() __init__
|
282
275
|
self.all_columns_displayed = True
|
283
276
|
self.all_rows_displayed = True
|
@@ -311,9 +304,12 @@ class MainTable(tk.Canvas):
|
|
311
304
|
self.txt_measure_canvas_text = self.txt_measure_canvas.create_text(0, 0, text="", font=self.PAR.ops.table_font)
|
312
305
|
|
313
306
|
self.RI.set_width(self.PAR.ops.default_row_index_width)
|
307
|
+
|
308
|
+
self.char_widths = {}
|
314
309
|
self.set_table_font_help()
|
315
310
|
self.set_header_font_help()
|
316
311
|
self.set_index_font_help()
|
312
|
+
|
317
313
|
self.data = kwargs["data_reference"]
|
318
314
|
if isinstance(self.data, (list, tuple)):
|
319
315
|
self.data = kwargs["data_reference"]
|
@@ -362,10 +358,8 @@ class MainTable(tk.Canvas):
|
|
362
358
|
reset_col_positions=False,
|
363
359
|
deselect_all=False,
|
364
360
|
)
|
361
|
+
self.rc_popup_menu, self.empty_rc_popup_menu = None, None
|
365
362
|
self.reset_col_positions()
|
366
|
-
|
367
|
-
self.rc_popup_menu = None
|
368
|
-
self.empty_rc_popup_menu = None
|
369
363
|
self.basic_bindings()
|
370
364
|
self.create_rc_menus()
|
371
365
|
|
@@ -377,7 +371,7 @@ class MainTable(tk.Canvas):
|
|
377
371
|
super().event_generate(*args, **kwargs)
|
378
372
|
|
379
373
|
def refresh(self, event: object = None) -> None:
|
380
|
-
self.
|
374
|
+
self.PAR.set_refresh_timer()
|
381
375
|
|
382
376
|
def window_configured(self, event: object) -> None:
|
383
377
|
w = self.PAR.winfo_width()
|
@@ -483,7 +477,7 @@ class MainTable(tk.Canvas):
|
|
483
477
|
dash=dash,
|
484
478
|
width=3,
|
485
479
|
outline=self.PAR.ops.resizing_line_fg if outline is None else outline,
|
486
|
-
|
480
|
+
tags="ctrl",
|
487
481
|
)
|
488
482
|
if delete_on_timer:
|
489
483
|
self.after(1500, self.delete_ctrl_outlines)
|
@@ -649,6 +643,8 @@ class MainTable(tk.Canvas):
|
|
649
643
|
find: str,
|
650
644
|
reverse: bool = False,
|
651
645
|
) -> tuple[int, int, int] | None:
|
646
|
+
if not self.selected:
|
647
|
+
return None
|
652
648
|
current_box = self.selection_boxes[self.selected.fill_iid]
|
653
649
|
current_id = self.selected.fill_iid
|
654
650
|
if is_last_cell(*current_box.coords, self.selected.row, self.selected.column, reverse=reverse):
|
@@ -742,13 +738,13 @@ class MainTable(tk.Canvas):
|
|
742
738
|
dash: tuple[int, int],
|
743
739
|
width: int,
|
744
740
|
outline: str,
|
745
|
-
|
741
|
+
tags: str | tuple[str, ...],
|
746
742
|
) -> None:
|
747
743
|
if self.hidd_ctrl_outline:
|
748
744
|
t, sh = self.hidd_ctrl_outline.popitem()
|
749
745
|
self.coords(t, x1, y1, x2, y2)
|
750
746
|
if sh:
|
751
|
-
self.itemconfig(t, fill=fill, dash=dash, width=width, outline=outline,
|
747
|
+
self.itemconfig(t, fill=fill, dash=dash, width=width, outline=outline, tags=tags)
|
752
748
|
else:
|
753
749
|
self.itemconfig(
|
754
750
|
t,
|
@@ -756,7 +752,7 @@ class MainTable(tk.Canvas):
|
|
756
752
|
dash=dash,
|
757
753
|
width=width,
|
758
754
|
outline=outline,
|
759
|
-
|
755
|
+
tags=tags,
|
760
756
|
state="normal",
|
761
757
|
)
|
762
758
|
self.lift(t)
|
@@ -770,7 +766,7 @@ class MainTable(tk.Canvas):
|
|
770
766
|
dash=dash,
|
771
767
|
width=width,
|
772
768
|
outline=outline,
|
773
|
-
|
769
|
+
tags=tags,
|
774
770
|
)
|
775
771
|
self.disp_ctrl_outline[t] = True
|
776
772
|
|
@@ -809,15 +805,20 @@ class MainTable(tk.Canvas):
|
|
809
805
|
)
|
810
806
|
return s, writer
|
811
807
|
|
812
|
-
def
|
813
|
-
|
814
|
-
|
815
|
-
event_data = event_dict(
|
816
|
-
name="begin_ctrl_c",
|
808
|
+
def new_event_dict(self, name: str, boxes: dict | None = None, state: bool = False) -> EventDataDict:
|
809
|
+
return event_dict(
|
810
|
+
name=name,
|
817
811
|
sheet=self.PAR.name,
|
818
812
|
widget=self,
|
813
|
+
boxes=self.get_boxes() if boxes is None else boxes,
|
819
814
|
selected=self.selected,
|
815
|
+
sheet_state=self.copy_sheet_state() if state else None,
|
820
816
|
)
|
817
|
+
|
818
|
+
def ctrl_c(self, event=None) -> None | EventDataDict:
|
819
|
+
if not self.selected:
|
820
|
+
return
|
821
|
+
event_data = self.new_event_dict("begin_ctrl_c")
|
821
822
|
boxes, maxrows = self.get_ctrl_x_c_boxes()
|
822
823
|
event_data["selection_boxes"] = boxes
|
823
824
|
s, writer = self.io_csv_writer()
|
@@ -862,12 +863,7 @@ class MainTable(tk.Canvas):
|
|
862
863
|
def ctrl_x(self, event=None, validation: bool = True) -> None | EventDataDict:
|
863
864
|
if not self.selected:
|
864
865
|
return
|
865
|
-
event_data =
|
866
|
-
name="edit_table",
|
867
|
-
sheet=self.PAR.name,
|
868
|
-
widget=self,
|
869
|
-
selected=self.selected,
|
870
|
-
)
|
866
|
+
event_data = self.new_event_dict("edit_table")
|
871
867
|
boxes, maxrows = self.get_ctrl_x_c_boxes()
|
872
868
|
event_data["selection_boxes"] = boxes
|
873
869
|
s, writer = self.io_csv_writer()
|
@@ -943,17 +939,64 @@ class MainTable(tk.Canvas):
|
|
943
939
|
self.PAR.emit_event("<<Cut>>", event_data)
|
944
940
|
return event_data
|
945
941
|
|
942
|
+
def sort_boxes(
|
943
|
+
self,
|
944
|
+
event: tk.Event | None = None,
|
945
|
+
boxes: AnyIter[int, int, int, int] | None = None,
|
946
|
+
reverse: bool = False,
|
947
|
+
row_wise: bool = False,
|
948
|
+
validation: bool = True,
|
949
|
+
key: Callable | None = None,
|
950
|
+
undo: bool = True,
|
951
|
+
) -> EventDataDict:
|
952
|
+
if boxes is None:
|
953
|
+
boxes = self.get_boxes()
|
954
|
+
if not boxes:
|
955
|
+
boxes = [(0, 0, len(self.row_positions) - 1, len(self.col_positions) - 1)]
|
956
|
+
event_data = self.new_event_dict("edit_table", boxes=boxes)
|
957
|
+
try_binding(self.extra_begin_sort_cells_func, event_data)
|
958
|
+
for r1, c1, r2, c2 in boxes:
|
959
|
+
data = sort_selection(
|
960
|
+
[[self.get_cell_data(self.datarn(r), self.datacn(c)) for c in range(c1, c2)] for r in range(r1, r2)],
|
961
|
+
reverse=reverse,
|
962
|
+
key=key,
|
963
|
+
row_wise=row_wise,
|
964
|
+
)
|
965
|
+
for ir, r in enumerate(range(r1, r2)):
|
966
|
+
data_r = self.datarn(r)
|
967
|
+
for ic, c in enumerate(range(c1, c2)):
|
968
|
+
data_c = self.datacn(c)
|
969
|
+
val = data[ir][ic]
|
970
|
+
if (
|
971
|
+
not self.edit_validation_func
|
972
|
+
or not validation
|
973
|
+
or (
|
974
|
+
self.edit_validation_func
|
975
|
+
and (val := self.edit_validation_func(mod_event_val(event_data, val, (data_r, data_c))))
|
976
|
+
is not None
|
977
|
+
)
|
978
|
+
):
|
979
|
+
event_data = self.event_data_set_cell(
|
980
|
+
datarn=data_r,
|
981
|
+
datacn=data_c,
|
982
|
+
value=val,
|
983
|
+
event_data=event_data,
|
984
|
+
)
|
985
|
+
if event_data["cells"]["table"]:
|
986
|
+
if undo and self.undo_enabled:
|
987
|
+
self.undo_stack.append(stored_event_dict(event_data))
|
988
|
+
try_binding(self.extra_end_sort_cells_func, event_data, "end_edit_table")
|
989
|
+
self.sheet_modified(event_data)
|
990
|
+
self.PAR.emit_event("<<SheetModified>>", event_data)
|
991
|
+
self.refresh()
|
992
|
+
return event_data
|
993
|
+
|
946
994
|
def ctrl_v(self, event: object = None, validation: bool = True) -> None | EventDataDict:
|
947
995
|
if not self.PAR.ops.paste_can_expand_x and len(self.col_positions) == 1:
|
948
996
|
return
|
949
997
|
if not self.PAR.ops.paste_can_expand_y and len(self.row_positions) == 1:
|
950
998
|
return
|
951
|
-
event_data =
|
952
|
-
name="edit_table",
|
953
|
-
sheet=self.PAR.name,
|
954
|
-
widget=self,
|
955
|
-
selected=self.selected,
|
956
|
-
)
|
999
|
+
event_data = self.new_event_dict("edit_table", state=True)
|
957
1000
|
if self.selected:
|
958
1001
|
selected_r = self.selected.box.from_r
|
959
1002
|
selected_c = self.selected.box.from_c
|
@@ -1210,12 +1253,7 @@ class MainTable(tk.Canvas):
|
|
1210
1253
|
def delete_key(self, event: object = None, validation: bool = True) -> None | EventDataDict:
|
1211
1254
|
if not self.selected:
|
1212
1255
|
return
|
1213
|
-
event_data =
|
1214
|
-
name="edit_table",
|
1215
|
-
sheet=self.PAR.name,
|
1216
|
-
widget=self,
|
1217
|
-
selected=self.selected,
|
1218
|
-
)
|
1256
|
+
event_data = self.new_event_dict("edit_table")
|
1219
1257
|
boxes = self.get_boxes()
|
1220
1258
|
event_data["selection_boxes"] = boxes
|
1221
1259
|
if not try_binding(self.extra_begin_delete_key_func, event_data, "begin_delete"):
|
@@ -1290,7 +1328,6 @@ class MainTable(tk.Canvas):
|
|
1290
1328
|
move_data: bool = True,
|
1291
1329
|
move_widths: bool = True,
|
1292
1330
|
create_selections: bool = True,
|
1293
|
-
data_indexes: bool = False,
|
1294
1331
|
event_data: EventDataDict | None = None,
|
1295
1332
|
) -> tuple[dict[int, int], dict[int, int], EventDataDict]:
|
1296
1333
|
self.saved_column_widths = {}
|
@@ -1299,22 +1336,17 @@ class MainTable(tk.Canvas):
|
|
1299
1336
|
if totalcols:
|
1300
1337
|
totalcols += 1
|
1301
1338
|
totalcols = self.equalize_data_row_lengths(at_least_cols=totalcols)
|
1302
|
-
if event_data
|
1303
|
-
event_data =
|
1304
|
-
|
1305
|
-
sheet=self.PAR.name,
|
1306
|
-
widget=self,
|
1307
|
-
boxes=self.get_boxes(),
|
1308
|
-
selected=self.selected,
|
1309
|
-
)
|
1339
|
+
if not event_data:
|
1340
|
+
event_data = self.new_event_dict("move_columns", state=True)
|
1341
|
+
if not event_data["moved"]["columns"]:
|
1310
1342
|
event_data["moved"]["columns"] = {
|
1311
1343
|
"data": data_new_idxs,
|
1312
1344
|
"displayed": {} if disp_new_idxs is None else disp_new_idxs,
|
1313
1345
|
}
|
1314
1346
|
event_data["options"] = self.copy_options()
|
1315
1347
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
1316
|
-
|
1317
|
-
|
1348
|
+
|
1349
|
+
if move_widths and disp_new_idxs:
|
1318
1350
|
self.set_col_positions(
|
1319
1351
|
itr=move_elements_by_mapping(
|
1320
1352
|
self.get_column_widths(),
|
@@ -1328,6 +1360,7 @@ class MainTable(tk.Canvas):
|
|
1328
1360
|
)
|
1329
1361
|
)
|
1330
1362
|
if create_selections:
|
1363
|
+
self.deselect("all", run_binding=False, redraw=False)
|
1331
1364
|
for boxst, boxend in consecutive_ranges(sorted(disp_new_idxs.values())):
|
1332
1365
|
self.create_selection_box(
|
1333
1366
|
0,
|
@@ -1337,6 +1370,8 @@ class MainTable(tk.Canvas):
|
|
1337
1370
|
"columns",
|
1338
1371
|
run_binding=True,
|
1339
1372
|
)
|
1373
|
+
else:
|
1374
|
+
self.recreate_all_selection_boxes()
|
1340
1375
|
if move_data:
|
1341
1376
|
self.data = list(
|
1342
1377
|
map(
|
@@ -1490,29 +1525,54 @@ class MainTable(tk.Canvas):
|
|
1490
1525
|
data_indexes: bool = False,
|
1491
1526
|
) -> tuple[dict[int, int], dict[int, int], int, dict[int, int]]:
|
1492
1527
|
if not data_indexes or self.all_rows_displayed:
|
1493
|
-
disp_new_idxs = get_new_indexes(
|
1528
|
+
disp_new_idxs = get_new_indexes(
|
1529
|
+
move_to=move_to,
|
1530
|
+
to_move=to_move,
|
1531
|
+
)
|
1532
|
+
data_new_idxs = dict(disp_new_idxs)
|
1494
1533
|
else:
|
1495
1534
|
disp_new_idxs = {}
|
1535
|
+
data_new_idxs = get_new_indexes(
|
1536
|
+
move_to=move_to,
|
1537
|
+
to_move=to_move,
|
1538
|
+
)
|
1496
1539
|
# move_to can be len and fix_data_len() takes index so - 1
|
1497
1540
|
fix_len = (move_to - 1) if move_to else move_to
|
1498
1541
|
if not self.all_rows_displayed and not data_indexes:
|
1499
1542
|
fix_len = self.datarn(fix_len)
|
1500
1543
|
self.fix_data_len(fix_len)
|
1501
1544
|
totalrows = max(self.total_data_rows(), len(self.row_positions) - 1)
|
1502
|
-
data_new_idxs = get_new_indexes(move_to=move_to, to_move=to_move)
|
1503
1545
|
if not self.all_rows_displayed and not data_indexes:
|
1504
|
-
|
1505
|
-
|
1546
|
+
keep = set(map(self.datarn, to_move))
|
1547
|
+
data_new_idxs = {
|
1548
|
+
k: v
|
1549
|
+
for k, v in zip(
|
1506
1550
|
move_elements_by_mapping(
|
1507
1551
|
self.displayed_rows,
|
1508
1552
|
data_new_idxs,
|
1509
1553
|
dict(zip(data_new_idxs.values(), data_new_idxs)),
|
1510
1554
|
),
|
1511
1555
|
self.displayed_rows,
|
1512
|
-
)
|
1513
|
-
|
1556
|
+
)
|
1557
|
+
if k in keep
|
1558
|
+
}
|
1514
1559
|
return data_new_idxs, dict(zip(data_new_idxs.values(), data_new_idxs)), totalrows, disp_new_idxs
|
1515
1560
|
|
1561
|
+
def move_rows_data(
|
1562
|
+
self,
|
1563
|
+
data_new_idxs: dict[int, int],
|
1564
|
+
data_old_idxs: dict[int, int],
|
1565
|
+
maxidx: int,
|
1566
|
+
) -> None:
|
1567
|
+
self.data = move_elements_by_mapping(
|
1568
|
+
self.data,
|
1569
|
+
data_new_idxs,
|
1570
|
+
data_old_idxs,
|
1571
|
+
)
|
1572
|
+
self.RI.fix_index(maxidx)
|
1573
|
+
if isinstance(self._row_index, list) and self._row_index:
|
1574
|
+
self._row_index = move_elements_by_mapping(self._row_index, data_new_idxs, data_old_idxs)
|
1575
|
+
|
1516
1576
|
def move_rows_adjust_options_dict(
|
1517
1577
|
self,
|
1518
1578
|
data_new_idxs: dict[int, int],
|
@@ -1522,8 +1582,9 @@ class MainTable(tk.Canvas):
|
|
1522
1582
|
move_data: bool = True,
|
1523
1583
|
move_heights: bool = True,
|
1524
1584
|
create_selections: bool = True,
|
1525
|
-
data_indexes: bool = False,
|
1526
1585
|
event_data: EventDataDict | None = None,
|
1586
|
+
undo_modification: EventDataDict | None = None,
|
1587
|
+
node_change: None | tuple[str, str, int] = None,
|
1527
1588
|
) -> tuple[dict[int, int], dict[int, int], EventDataDict]:
|
1528
1589
|
self.saved_row_heights = {}
|
1529
1590
|
if not isinstance(totalrows, int):
|
@@ -1533,54 +1594,33 @@ class MainTable(tk.Canvas):
|
|
1533
1594
|
max(data_new_idxs.values(), default=0),
|
1534
1595
|
)
|
1535
1596
|
self.fix_data_len(totalrows - 1)
|
1536
|
-
if event_data
|
1537
|
-
event_data =
|
1538
|
-
|
1539
|
-
sheet=self.PAR.name,
|
1540
|
-
widget=self,
|
1541
|
-
boxes=self.get_boxes(),
|
1542
|
-
selected=self.selected,
|
1543
|
-
)
|
1597
|
+
if not event_data:
|
1598
|
+
event_data = self.new_event_dict("move_rows", state=True)
|
1599
|
+
if not event_data["moved"]["rows"]:
|
1544
1600
|
event_data["moved"]["rows"] = {
|
1545
1601
|
"data": data_new_idxs,
|
1546
1602
|
"displayed": {} if disp_new_idxs is None else disp_new_idxs,
|
1547
1603
|
}
|
1548
1604
|
event_data["options"] = self.copy_options()
|
1549
1605
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
1550
|
-
|
1551
|
-
self.deselect("all", run_binding=False, redraw=False)
|
1552
|
-
self.set_row_positions(
|
1553
|
-
itr=move_elements_by_mapping(
|
1554
|
-
self.get_row_heights(),
|
1555
|
-
disp_new_idxs,
|
1556
|
-
dict(
|
1557
|
-
zip(
|
1558
|
-
disp_new_idxs.values(),
|
1559
|
-
disp_new_idxs,
|
1560
|
-
)
|
1561
|
-
),
|
1562
|
-
)
|
1563
|
-
)
|
1564
|
-
if create_selections:
|
1565
|
-
for boxst, boxend in consecutive_ranges(sorted(disp_new_idxs.values())):
|
1566
|
-
self.create_selection_box(
|
1567
|
-
boxst,
|
1568
|
-
0,
|
1569
|
-
boxend,
|
1570
|
-
len(self.col_positions) - 1,
|
1571
|
-
"rows",
|
1572
|
-
run_binding=True,
|
1573
|
-
)
|
1606
|
+
|
1574
1607
|
if move_data:
|
1575
|
-
self.data = move_elements_by_mapping(
|
1576
|
-
self.data,
|
1577
|
-
data_new_idxs,
|
1578
|
-
data_old_idxs,
|
1579
|
-
)
|
1580
1608
|
maxidx = len_to_idx(totalrows)
|
1581
|
-
self.
|
1582
|
-
|
1583
|
-
|
1609
|
+
if self.PAR.ops.treeview:
|
1610
|
+
two_step_move = self.RI.move_rows_mod_nodes(
|
1611
|
+
data_new_idxs=data_new_idxs,
|
1612
|
+
data_old_idxs=data_old_idxs,
|
1613
|
+
disp_new_idxs=disp_new_idxs,
|
1614
|
+
maxidx=maxidx,
|
1615
|
+
event_data=event_data,
|
1616
|
+
undo_modification=undo_modification,
|
1617
|
+
node_change=node_change,
|
1618
|
+
)
|
1619
|
+
data_new_idxs, data_old_idxs, disp_new_idxs, event_data = next(two_step_move)
|
1620
|
+
if not data_new_idxs and not disp_new_idxs:
|
1621
|
+
return data_new_idxs, disp_new_idxs, event_data
|
1622
|
+
else:
|
1623
|
+
self.move_rows_data(data_new_idxs, data_old_idxs, maxidx)
|
1584
1624
|
maxidx = self.get_max_row_idx(maxidx)
|
1585
1625
|
full_new_idxs = self.get_full_new_idxs(
|
1586
1626
|
max_idx=maxidx,
|
@@ -1598,6 +1638,9 @@ class MainTable(tk.Canvas):
|
|
1598
1638
|
self.RI.cell_options = {full_new_idxs[k]: v for k, v in self.RI.cell_options.items()}
|
1599
1639
|
self.RI.tree_rns = {v: full_new_idxs[k] for v, k in self.RI.tree_rns.items()}
|
1600
1640
|
self.displayed_rows = sorted(full_new_idxs[k] for k in self.displayed_rows)
|
1641
|
+
if self.PAR.ops.treeview:
|
1642
|
+
next(two_step_move)
|
1643
|
+
|
1601
1644
|
if self.named_spans:
|
1602
1645
|
totalcols = self.total_data_cols()
|
1603
1646
|
new_ops = self.PAR.create_options_from_span
|
@@ -1696,6 +1739,33 @@ class MainTable(tk.Canvas):
|
|
1696
1739
|
del self.cell_options[(full_new_idxs[k], c)][span["type_"]]
|
1697
1740
|
# finally, change the span coords
|
1698
1741
|
span["from_r"], span["upto_r"] = newfrom, newupto
|
1742
|
+
|
1743
|
+
if move_heights and disp_new_idxs:
|
1744
|
+
self.set_row_positions(
|
1745
|
+
itr=move_elements_by_mapping(
|
1746
|
+
self.get_row_heights(),
|
1747
|
+
disp_new_idxs,
|
1748
|
+
dict(
|
1749
|
+
zip(
|
1750
|
+
disp_new_idxs.values(),
|
1751
|
+
disp_new_idxs,
|
1752
|
+
)
|
1753
|
+
),
|
1754
|
+
)
|
1755
|
+
)
|
1756
|
+
if create_selections:
|
1757
|
+
self.deselect("all", run_binding=False, redraw=False)
|
1758
|
+
for boxst, boxend in consecutive_ranges(sorted(disp_new_idxs.values())):
|
1759
|
+
self.create_selection_box(
|
1760
|
+
boxst,
|
1761
|
+
0,
|
1762
|
+
boxend,
|
1763
|
+
len(self.col_positions) - 1,
|
1764
|
+
"rows",
|
1765
|
+
run_binding=True,
|
1766
|
+
)
|
1767
|
+
else:
|
1768
|
+
self.recreate_all_selection_boxes()
|
1699
1769
|
return data_new_idxs, disp_new_idxs, event_data
|
1700
1770
|
|
1701
1771
|
def get_max_row_idx(self, maxidx: int | None = None) -> int:
|
@@ -1812,7 +1882,7 @@ class MainTable(tk.Canvas):
|
|
1812
1882
|
event_data["cells"]["table"][k] = self.get_cell_data(k[0], k[1])
|
1813
1883
|
return event_data
|
1814
1884
|
|
1815
|
-
def
|
1885
|
+
def restore_sheet_state(self, modification: EventDataDict) -> None:
|
1816
1886
|
if "cell_options" in modification["options"]:
|
1817
1887
|
self.cell_options = modification["options"]["cell_options"]
|
1818
1888
|
if "column_options" in modification["options"]:
|
@@ -1829,17 +1899,25 @@ class MainTable(tk.Canvas):
|
|
1829
1899
|
self.tagged_rows = modification["options"]["tagged_rows"]
|
1830
1900
|
if "tagged_columns" in modification["options"]:
|
1831
1901
|
self.tagged_columns = modification["options"]["tagged_columns"]
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1902
|
+
if modification["named_spans"]:
|
1903
|
+
self.named_spans = {
|
1904
|
+
k: mod_span_widget(unpickle_obj(v), self.PAR) for k, v in modification["named_spans"].items()
|
1905
|
+
}
|
1906
|
+
if modification["sheet_state"]:
|
1907
|
+
self.RI.tree_open_ids = modification["sheet_state"]["tree_open_ids"]
|
1908
|
+
self.row_positions = modification["sheet_state"]["row_positions"]
|
1909
|
+
self.col_positions = modification["sheet_state"]["col_positions"]
|
1910
|
+
self.displayed_rows = modification["sheet_state"]["displayed_rows"]
|
1911
|
+
self.displayed_columns = modification["sheet_state"]["displayed_columns"]
|
1912
|
+
self.all_rows_displayed = modification["sheet_state"]["all_rows_displayed"]
|
1913
|
+
self.all_columns_displayed = modification["sheet_state"]["all_columns_displayed"]
|
1914
|
+
self.saved_row_heights = modification["sheet_state"]["saved_row_heights"]
|
1915
|
+
self.saved_column_widths = modification["sheet_state"]["saved_column_widths"]
|
1916
|
+
self.recreate_all_selection_boxes()
|
1835
1917
|
|
1836
1918
|
def undo_modification_invert_event(self, modification: EventDataDict, name: str = "undo") -> EventDataDict:
|
1837
1919
|
self.deselect("all", redraw=False)
|
1838
|
-
event_data =
|
1839
|
-
name=modification["eventname"],
|
1840
|
-
sheet=self.PAR.name,
|
1841
|
-
widget=self,
|
1842
|
-
)
|
1920
|
+
event_data = self.new_event_dict(modification["eventname"], state=True)
|
1843
1921
|
event_data["selection_boxes"] = modification["selection_boxes"]
|
1844
1922
|
event_data["selected"] = modification["selected"]
|
1845
1923
|
saved_cells = False
|
@@ -1870,7 +1948,6 @@ class MainTable(tk.Canvas):
|
|
1870
1948
|
"data": data_new_idxs,
|
1871
1949
|
"displayed": disp_new_idxs,
|
1872
1950
|
}
|
1873
|
-
self.restore_options_named_spans(modification)
|
1874
1951
|
|
1875
1952
|
if modification["moved"]["rows"]:
|
1876
1953
|
totalrows = max(self.total_data_rows(), max(modification["moved"]["rows"]["data"].values()))
|
@@ -1890,12 +1967,12 @@ class MainTable(tk.Canvas):
|
|
1890
1967
|
)
|
1891
1968
|
),
|
1892
1969
|
event_data=event_data,
|
1970
|
+
undo_modification=modification,
|
1893
1971
|
)
|
1894
1972
|
event_data["moved"]["rows"] = {
|
1895
1973
|
"data": data_new_idxs,
|
1896
1974
|
"displayed": disp_new_idxs,
|
1897
1975
|
}
|
1898
|
-
self.restore_options_named_spans(modification)
|
1899
1976
|
|
1900
1977
|
if modification["added"]["rows"]:
|
1901
1978
|
self.deselect("all", run_binding=False, redraw=False)
|
@@ -1906,8 +1983,8 @@ class MainTable(tk.Canvas):
|
|
1906
1983
|
event_data = self.delete_rows_displayed(
|
1907
1984
|
rows=tuple(reversed(modification["added"]["rows"]["row_heights"])),
|
1908
1985
|
event_data=event_data,
|
1986
|
+
restored_state=True,
|
1909
1987
|
)
|
1910
|
-
self.displayed_rows = modification["added"]["rows"]["displayed_rows"]
|
1911
1988
|
|
1912
1989
|
if modification["added"]["columns"]:
|
1913
1990
|
self.deselect("all", run_binding=False, redraw=False)
|
@@ -1918,21 +1995,21 @@ class MainTable(tk.Canvas):
|
|
1918
1995
|
event_data = self.delete_columns_displayed(
|
1919
1996
|
cols=tuple(reversed(modification["added"]["columns"]["column_widths"])),
|
1920
1997
|
event_data=event_data,
|
1998
|
+
restored_state=True,
|
1921
1999
|
)
|
1922
|
-
self.displayed_columns = modification["added"]["columns"]["displayed_columns"]
|
1923
2000
|
|
1924
2001
|
if modification["deleted"]["rows"] or modification["deleted"]["row_heights"]:
|
2002
|
+
event_data["treeview"] = modification["treeview"]
|
1925
2003
|
self.add_rows(
|
1926
2004
|
rows=modification["deleted"]["rows"],
|
1927
2005
|
index=modification["deleted"]["index"],
|
1928
2006
|
row_heights=modification["deleted"]["row_heights"],
|
1929
2007
|
event_data=event_data,
|
1930
|
-
displayed_rows=modification["deleted"]["displayed_rows"],
|
1931
2008
|
create_ops=False,
|
1932
|
-
create_selections=
|
2009
|
+
create_selections=False,
|
1933
2010
|
add_col_positions=False,
|
2011
|
+
restored_state=True,
|
1934
2012
|
)
|
1935
|
-
self.restore_options_named_spans(modification)
|
1936
2013
|
|
1937
2014
|
if modification["deleted"]["columns"] or modification["deleted"]["column_widths"]:
|
1938
2015
|
self.add_columns(
|
@@ -1940,12 +2017,11 @@ class MainTable(tk.Canvas):
|
|
1940
2017
|
header=modification["deleted"]["header"],
|
1941
2018
|
column_widths=modification["deleted"]["column_widths"],
|
1942
2019
|
event_data=event_data,
|
1943
|
-
displayed_columns=modification["deleted"]["displayed_columns"],
|
1944
2020
|
create_ops=False,
|
1945
|
-
create_selections=
|
2021
|
+
create_selections=False,
|
1946
2022
|
add_row_positions=False,
|
2023
|
+
restored_state=True,
|
1947
2024
|
)
|
1948
|
-
self.restore_options_named_spans(modification)
|
1949
2025
|
|
1950
2026
|
if modification["eventname"].startswith(("edit", "move")):
|
1951
2027
|
if not saved_cells:
|
@@ -1958,6 +2034,8 @@ class MainTable(tk.Canvas):
|
|
1958
2034
|
elif modification["eventname"].startswith("delete"):
|
1959
2035
|
event_data["eventname"] = modification["eventname"].replace("delete", "add")
|
1960
2036
|
|
2037
|
+
self.restore_sheet_state(modification)
|
2038
|
+
|
1961
2039
|
if not modification["eventname"].startswith("move") and (
|
1962
2040
|
len(self.row_positions) > 1 or len(self.col_positions) > 1
|
1963
2041
|
):
|
@@ -2014,9 +2092,9 @@ class MainTable(tk.Canvas):
|
|
2014
2092
|
need_redraw = True
|
2015
2093
|
else:
|
2016
2094
|
if r is not None and not keep_yscroll:
|
2017
|
-
y =
|
2018
|
-
|
2019
|
-
|
2095
|
+
y = max(
|
2096
|
+
0, int(self.row_positions[r] + ((self.row_positions[r + 1] - self.row_positions[r]) * r_pc)) - 2
|
2097
|
+
)
|
2020
2098
|
y = y / (self.row_positions[-1] + self.PAR.ops.empty_vertical)
|
2021
2099
|
args = [
|
2022
2100
|
"moveto",
|
@@ -2041,9 +2119,9 @@ class MainTable(tk.Canvas):
|
|
2041
2119
|
need_redraw = True
|
2042
2120
|
else:
|
2043
2121
|
if c is not None and not keep_xscroll:
|
2044
|
-
x =
|
2045
|
-
|
2046
|
-
|
2122
|
+
x = max(
|
2123
|
+
0, int(self.col_positions[c] + ((self.col_positions[c + 1] - self.col_positions[c]) * c_pc)) - 2
|
2124
|
+
)
|
2047
2125
|
x = x / (self.col_positions[-1] + self.PAR.ops.empty_horizontal)
|
2048
2126
|
args = [
|
2049
2127
|
"moveto",
|
@@ -2394,15 +2472,11 @@ class MainTable(tk.Canvas):
|
|
2394
2472
|
def page_UP(self, event: object = None) -> None:
|
2395
2473
|
height = self.winfo_height()
|
2396
2474
|
top = self.canvasy(0)
|
2397
|
-
scrollto_y = top - height
|
2398
|
-
if scrollto_y < 0:
|
2399
|
-
scrollto_y = 0
|
2475
|
+
scrollto_y = max(0, top - height)
|
2400
2476
|
if self.PAR.ops.page_up_down_select_row:
|
2401
2477
|
r = bisect_left(self.row_positions, scrollto_y)
|
2402
2478
|
if self.selected and self.selected.row == r:
|
2403
|
-
r
|
2404
|
-
if r < 0:
|
2405
|
-
r = 0
|
2479
|
+
r = max(0, r - 1)
|
2406
2480
|
if self.RI.row_selection_enabled and (
|
2407
2481
|
self.anything_selected(exclude_columns=True, exclude_cells=True) or not self.anything_selected()
|
2408
2482
|
):
|
@@ -2854,7 +2928,7 @@ class MainTable(tk.Canvas):
|
|
2854
2928
|
self.menu_add_command(
|
2855
2929
|
self.CH.ch_rc_popup_menu,
|
2856
2930
|
label=self.PAR.ops.delete_columns_label,
|
2857
|
-
command=self.
|
2931
|
+
command=self.delete_columns,
|
2858
2932
|
**mnkwgs,
|
2859
2933
|
)
|
2860
2934
|
if self.rc_insert_column_enabled:
|
@@ -2880,7 +2954,7 @@ class MainTable(tk.Canvas):
|
|
2880
2954
|
self.menu_add_command(
|
2881
2955
|
self.RI.ri_rc_popup_menu,
|
2882
2956
|
label=self.PAR.ops.delete_rows_label,
|
2883
|
-
command=self.
|
2957
|
+
command=self.delete_rows,
|
2884
2958
|
**mnkwgs,
|
2885
2959
|
)
|
2886
2960
|
if self.rc_insert_row_enabled:
|
@@ -2902,6 +2976,99 @@ class MainTable(tk.Canvas):
|
|
2902
2976
|
command=lambda: self.rc_add_rows("below"),
|
2903
2977
|
**mnkwgs,
|
2904
2978
|
)
|
2979
|
+
if self.rc_sort_cells_enabled:
|
2980
|
+
self.menu_add_command(
|
2981
|
+
self.rc_popup_menu,
|
2982
|
+
label=self.PAR.ops.sort_cells_label,
|
2983
|
+
accelerator=self.PAR.ops.sort_cells_accelerator,
|
2984
|
+
command=self.sort_boxes,
|
2985
|
+
**mnkwgs,
|
2986
|
+
)
|
2987
|
+
self.menu_add_command(
|
2988
|
+
self.rc_popup_menu,
|
2989
|
+
label=self.PAR.ops.sort_cells_reverse_label,
|
2990
|
+
accelerator=self.PAR.ops.sort_cells_reverse_accelerator,
|
2991
|
+
command=lambda: self.sort_boxes(reverse=True),
|
2992
|
+
**mnkwgs,
|
2993
|
+
)
|
2994
|
+
self.menu_add_command(
|
2995
|
+
self.rc_popup_menu,
|
2996
|
+
label=self.PAR.ops.sort_cells_x_label,
|
2997
|
+
accelerator=self.PAR.ops.sort_cells_x_accelerator,
|
2998
|
+
command=lambda: self.sort_boxes(row_wise=True),
|
2999
|
+
**mnkwgs,
|
3000
|
+
)
|
3001
|
+
self.menu_add_command(
|
3002
|
+
self.rc_popup_menu,
|
3003
|
+
label=self.PAR.ops.sort_cells_x_reverse_label,
|
3004
|
+
accelerator=self.PAR.ops.sort_cells_x_reverse_accelerator,
|
3005
|
+
command=lambda: self.sort_boxes(reverse=True, row_wise=True),
|
3006
|
+
**mnkwgs,
|
3007
|
+
)
|
3008
|
+
# row index sort rows cells
|
3009
|
+
if self.rc_sort_row_enabled:
|
3010
|
+
self.menu_add_command(
|
3011
|
+
self.RI.ri_rc_popup_menu,
|
3012
|
+
label=self.PAR.ops.sort_row_label,
|
3013
|
+
accelerator=self.PAR.ops.sort_row_accelerator,
|
3014
|
+
command=self.RI._sort_rows,
|
3015
|
+
**mnkwgs,
|
3016
|
+
)
|
3017
|
+
self.menu_add_command(
|
3018
|
+
self.RI.ri_rc_popup_menu,
|
3019
|
+
label=self.PAR.ops.sort_row_reverse_label,
|
3020
|
+
accelerator=self.PAR.ops.sort_row_reverse_accelerator,
|
3021
|
+
command=lambda: self.RI._sort_rows(reverse=True),
|
3022
|
+
**mnkwgs,
|
3023
|
+
)
|
3024
|
+
# header sort columns cells
|
3025
|
+
if self.rc_sort_column_enabled:
|
3026
|
+
self.menu_add_command(
|
3027
|
+
self.CH.ch_rc_popup_menu,
|
3028
|
+
label=self.PAR.ops.sort_column_label,
|
3029
|
+
accelerator=self.PAR.ops.sort_column_accelerator,
|
3030
|
+
command=self.CH._sort_columns,
|
3031
|
+
**mnkwgs,
|
3032
|
+
)
|
3033
|
+
self.menu_add_command(
|
3034
|
+
self.CH.ch_rc_popup_menu,
|
3035
|
+
label=self.PAR.ops.sort_column_reverse_label,
|
3036
|
+
accelerator=self.PAR.ops.sort_column_reverse_accelerator,
|
3037
|
+
command=lambda: self.CH._sort_columns(reverse=True),
|
3038
|
+
**mnkwgs,
|
3039
|
+
)
|
3040
|
+
# row index sort columns by row
|
3041
|
+
if self.rc_sort_columns_enabled:
|
3042
|
+
self.menu_add_command(
|
3043
|
+
self.RI.ri_rc_popup_menu,
|
3044
|
+
label=self.PAR.ops.sort_columns_label,
|
3045
|
+
accelerator=self.PAR.ops.sort_columns_accelerator,
|
3046
|
+
command=self.RI._sort_columns_by_row,
|
3047
|
+
**mnkwgs,
|
3048
|
+
)
|
3049
|
+
self.menu_add_command(
|
3050
|
+
self.RI.ri_rc_popup_menu,
|
3051
|
+
label=self.PAR.ops.sort_columns_reverse_label,
|
3052
|
+
accelerator=self.PAR.ops.sort_columns_reverse_accelerator,
|
3053
|
+
command=lambda: self.RI._sort_columns_by_row(reverse=True),
|
3054
|
+
**mnkwgs,
|
3055
|
+
)
|
3056
|
+
# header sort rows by column
|
3057
|
+
if self.rc_sort_rows_enabled:
|
3058
|
+
self.menu_add_command(
|
3059
|
+
self.CH.ch_rc_popup_menu,
|
3060
|
+
label=self.PAR.ops.sort_rows_label,
|
3061
|
+
accelerator=self.PAR.ops.sort_rows_accelerator,
|
3062
|
+
command=self.CH._sort_rows_by_column,
|
3063
|
+
**mnkwgs,
|
3064
|
+
)
|
3065
|
+
self.menu_add_command(
|
3066
|
+
self.CH.ch_rc_popup_menu,
|
3067
|
+
label=self.PAR.ops.sort_rows_reverse_label,
|
3068
|
+
accelerator=self.PAR.ops.sort_rows_reverse_accelerator,
|
3069
|
+
command=lambda: self.CH._sort_rows_by_column(reverse=True),
|
3070
|
+
**mnkwgs,
|
3071
|
+
)
|
2905
3072
|
for label, func in self.extra_table_rc_menu_funcs.items():
|
2906
3073
|
self.menu_add_command(
|
2907
3074
|
self.rc_popup_menu,
|
@@ -3072,6 +3239,16 @@ class MainTable(tk.Canvas):
|
|
3072
3239
|
self.rc_insert_row_enabled = True
|
3073
3240
|
self.rc_popup_menus_enabled = True
|
3074
3241
|
self.rc_select_enabled = True
|
3242
|
+
if binding in ("all", "sort_cells"):
|
3243
|
+
self.rc_sort_cells_enabled = True
|
3244
|
+
if binding in ("all", "sort_row"):
|
3245
|
+
self.rc_sort_row_enabled = True
|
3246
|
+
if binding in ("all", "sort_column", "sort_col"):
|
3247
|
+
self.rc_sort_column_enabled = True
|
3248
|
+
if binding in ("all", "sort_columns", "sort_cols"):
|
3249
|
+
self.rc_sort_columns_enabled = True
|
3250
|
+
if binding in ("all", "sort_rows"):
|
3251
|
+
self.rc_sort_rows_enabled = True
|
3075
3252
|
if binding in ("all", "right_click_popup_menu", "rc_popup_menu", "rc_menu"):
|
3076
3253
|
self.rc_popup_menus_enabled = True
|
3077
3254
|
self.rc_select_enabled = True
|
@@ -3145,6 +3322,16 @@ class MainTable(tk.Canvas):
|
|
3145
3322
|
self.rc_insert_column_enabled = False
|
3146
3323
|
if binding in bind_add_rows:
|
3147
3324
|
self.rc_insert_row_enabled = False
|
3325
|
+
if binding in ("all", "sort_cells"):
|
3326
|
+
self.rc_sort_cells_enabled = False
|
3327
|
+
if binding in ("all", "sort_row"):
|
3328
|
+
self.rc_sort_row_enabled = False
|
3329
|
+
if binding in ("all", "sort_column", "sort_col"):
|
3330
|
+
self.rc_sort_column_enabled = False
|
3331
|
+
if binding in ("all", "sort_columns", "sort_cols"):
|
3332
|
+
self.rc_sort_columns_enabled = False
|
3333
|
+
if binding in ("all", "sort_rows"):
|
3334
|
+
self.rc_sort_rows_enabled = False
|
3148
3335
|
if binding in ("all", "right_click_popup_menu", "rc_popup_menu", "rc_menu"):
|
3149
3336
|
self.rc_popup_menus_enabled = False
|
3150
3337
|
if binding in ("all", "right_click_select", "rc_select"):
|
@@ -3290,12 +3477,12 @@ class MainTable(tk.Canvas):
|
|
3290
3477
|
t, sh = self.hidd_resize_lines.popitem()
|
3291
3478
|
self.coords(t, x1, y1, x2, y2)
|
3292
3479
|
if sh:
|
3293
|
-
self.itemconfig(t, width=width, fill=fill,
|
3480
|
+
self.itemconfig(t, width=width, fill=fill, tags=tag)
|
3294
3481
|
else:
|
3295
|
-
self.itemconfig(t, width=width, fill=fill,
|
3482
|
+
self.itemconfig(t, width=width, fill=fill, tags=tag, state="normal")
|
3296
3483
|
self.lift(t)
|
3297
3484
|
else:
|
3298
|
-
t = self.create_line(x1, y1, x2, y2, width=width, fill=fill,
|
3485
|
+
t = self.create_line(x1, y1, x2, y2, width=width, fill=fill, tags=tag)
|
3299
3486
|
self.disp_resize_lines[t] = True
|
3300
3487
|
|
3301
3488
|
def delete_resize_lines(self):
|
@@ -3803,38 +3990,14 @@ class MainTable(tk.Canvas):
|
|
3803
3990
|
c_pc = 0.0
|
3804
3991
|
old_min_row_height = int(self.min_row_height)
|
3805
3992
|
old_default_row_height = int(self.get_default_row_height())
|
3806
|
-
self.set_table_font(
|
3807
|
-
|
3808
|
-
reset_row_positions=False,
|
3809
|
-
)
|
3810
|
-
self.set_index_font(index_font)
|
3993
|
+
self.set_table_font(table_font, row_heights=False)
|
3994
|
+
self.set_index_font(index_font, row_heights=False)
|
3811
3995
|
self.set_header_font(header_font)
|
3812
3996
|
if self.PAR.ops.set_cell_sizes_on_zoom:
|
3813
3997
|
self.set_all_cell_sizes_to_text()
|
3814
3998
|
self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
3815
3999
|
elif not self.PAR.ops.set_cell_sizes_on_zoom:
|
3816
|
-
|
3817
|
-
self.row_positions = list(
|
3818
|
-
accumulate(
|
3819
|
-
chain(
|
3820
|
-
[0],
|
3821
|
-
(
|
3822
|
-
(
|
3823
|
-
self.min_row_height
|
3824
|
-
if h == old_min_row_height
|
3825
|
-
else (
|
3826
|
-
default_row_height
|
3827
|
-
if h == old_default_row_height
|
3828
|
-
else self.min_row_height
|
3829
|
-
if h < self.min_row_height
|
3830
|
-
else h
|
3831
|
-
)
|
3832
|
-
)
|
3833
|
-
for h in self.gen_row_heights()
|
3834
|
-
),
|
3835
|
-
)
|
3836
|
-
)
|
3837
|
-
)
|
4000
|
+
self.change_font_manage_row_heights(old_min_row_height, old_default_row_height)
|
3838
4001
|
self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
3839
4002
|
self.recreate_all_selection_boxes()
|
3840
4003
|
self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
@@ -3878,13 +4041,20 @@ class MainTable(tk.Canvas):
|
|
3878
4041
|
return b[2] - b[0], b[3] - b[1]
|
3879
4042
|
|
3880
4043
|
def get_lines_cell_height(self, n: int, font: None | FontTuple = None) -> int:
|
3881
|
-
|
3882
|
-
self.
|
4044
|
+
if font == self.PAR.ops.table_font:
|
4045
|
+
return 3 + (n * self.table_txt_height)
|
4046
|
+
|
4047
|
+
elif font == self.PAR.ops.index_font:
|
4048
|
+
return 3 + (n * self.index_txt_height)
|
4049
|
+
|
4050
|
+
elif font == self.PAR.ops.header_font:
|
4051
|
+
return 3 + (n * self.header_txt_height)
|
4052
|
+
|
4053
|
+
else:
|
4054
|
+
return 3 + self.get_txt_h(
|
3883
4055
|
txt="\n".join("|" for _ in range(n)) if n > 1 else "|",
|
3884
|
-
font=
|
4056
|
+
font=font,
|
3885
4057
|
)
|
3886
|
-
+ 5
|
3887
|
-
)
|
3888
4058
|
|
3889
4059
|
def set_min_column_width(self, width: int) -> None:
|
3890
4060
|
if width:
|
@@ -3915,92 +4085,101 @@ class MainTable(tk.Canvas):
|
|
3915
4085
|
)
|
3916
4086
|
return self.PAR.ops.default_header_height
|
3917
4087
|
|
3918
|
-
def
|
4088
|
+
def check_font(self, newfont: tuple) -> None:
|
4089
|
+
if (
|
4090
|
+
not isinstance(newfont, tuple)
|
4091
|
+
or len(newfont) != 3
|
4092
|
+
or not isinstance(newfont[0], str)
|
4093
|
+
or not isinstance(newfont[1], int)
|
4094
|
+
or not isinstance(newfont[2], str)
|
4095
|
+
):
|
4096
|
+
raise ValueError(font_value_error)
|
4097
|
+
|
4098
|
+
def set_table_font(self, newfont: tuple | None = None, row_heights: bool = True) -> tuple[str, int, str]:
|
3919
4099
|
if newfont:
|
3920
|
-
|
3921
|
-
raise ValueError("Argument must be tuple e.g. ('Carlito', 12, 'normal')")
|
3922
|
-
if len(newfont) != 3:
|
3923
|
-
raise ValueError("Argument must be three-tuple")
|
3924
|
-
if not isinstance(newfont[0], str) or not isinstance(newfont[1], int) or not isinstance(newfont[2], str):
|
3925
|
-
raise ValueError(
|
3926
|
-
"Argument must be font, size and 'normal', 'bold' or'italic' e.g. ('Carlito',12,'normal')"
|
3927
|
-
)
|
4100
|
+
self.check_font(newfont)
|
3928
4101
|
self.PAR.ops.table_font = FontTuple(*newfont)
|
4102
|
+
old_min_row_height = int(self.min_row_height)
|
4103
|
+
old_default_row_height = int(self.get_default_row_height())
|
3929
4104
|
self.set_table_font_help()
|
3930
|
-
if
|
3931
|
-
|
3932
|
-
self.reset_row_positions()
|
3933
|
-
else:
|
3934
|
-
self.set_row_positions(itr=reset_row_positions)
|
4105
|
+
if row_heights:
|
4106
|
+
self.change_font_manage_row_heights(old_min_row_height, old_default_row_height)
|
3935
4107
|
self.recreate_all_selection_boxes()
|
3936
4108
|
return self.PAR.ops.table_font
|
3937
4109
|
|
3938
4110
|
def set_table_font_help(self):
|
4111
|
+
self.table_font = self.PAR.ops.table_font
|
4112
|
+
if self.PAR.ops.table_font not in self.char_widths:
|
4113
|
+
self.char_widths[self.PAR.ops.table_font] = {}
|
4114
|
+
self.table_test_str_w = self.get_txt_w(_test_str)
|
3939
4115
|
self.table_txt_width, self.table_txt_height = self.get_txt_dimensions("|", self.PAR.ops.table_font)
|
3940
|
-
self.
|
3941
|
-
if not self.table_half_txt_height % 2:
|
3942
|
-
self.table_first_ln_ins = self.table_half_txt_height + 2
|
3943
|
-
else:
|
3944
|
-
self.table_first_ln_ins = self.table_half_txt_height + 3
|
3945
|
-
self.min_row_height = int(self.table_first_ln_ins * 2.22)
|
3946
|
-
self.table_xtra_lines_increment = int(self.table_txt_height)
|
3947
|
-
if self.min_row_height < 12:
|
3948
|
-
self.min_row_height = 12
|
4116
|
+
self.min_row_height = max(6, self.table_txt_height, self.index_txt_height) + 6
|
3949
4117
|
|
3950
|
-
def
|
4118
|
+
def set_index_font(self, newfont: tuple | None = None, row_heights: bool = True) -> tuple[str, int, str]:
|
3951
4119
|
if newfont:
|
3952
|
-
|
3953
|
-
|
3954
|
-
|
3955
|
-
|
3956
|
-
|
3957
|
-
|
3958
|
-
|
3959
|
-
)
|
3960
|
-
|
3961
|
-
self.set_header_font_help()
|
3962
|
-
self.recreate_all_selection_boxes()
|
3963
|
-
return self.PAR.ops.header_font
|
4120
|
+
self.check_font(newfont)
|
4121
|
+
self.PAR.ops.index_font = FontTuple(*newfont)
|
4122
|
+
old_min_row_height = int(self.min_row_height)
|
4123
|
+
old_default_row_height = int(self.get_default_row_height())
|
4124
|
+
self.set_index_font_help()
|
4125
|
+
if row_heights:
|
4126
|
+
self.change_font_manage_row_heights(old_min_row_height, old_default_row_height)
|
4127
|
+
self.recreate_all_selection_boxes()
|
4128
|
+
return self.PAR.ops.index_font
|
3964
4129
|
|
3965
|
-
def
|
3966
|
-
self.
|
3967
|
-
self.
|
3968
|
-
|
3969
|
-
|
3970
|
-
|
3971
|
-
|
3972
|
-
self.header_xtra_lines_increment = self.header_txt_height
|
3973
|
-
self.min_header_height = int(self.header_first_ln_ins * 2.22)
|
3974
|
-
if (
|
3975
|
-
isinstance(self.PAR.ops.default_header_height, int)
|
3976
|
-
and self.PAR.ops.default_header_height < self.min_header_height
|
3977
|
-
):
|
3978
|
-
self.PAR.ops.default_header_height = int(self.min_header_height)
|
3979
|
-
self.CH.set_height(self.get_default_header_height(), set_TL=True)
|
4130
|
+
def set_index_font_help(self):
|
4131
|
+
self.RI.index_font = self.PAR.ops.index_font
|
4132
|
+
if self.PAR.ops.index_font not in self.char_widths:
|
4133
|
+
self.char_widths[self.PAR.ops.index_font] = {}
|
4134
|
+
self.RI.index_test_str_w = self.get_txt_w(_test_str, self.PAR.ops.index_font)
|
4135
|
+
self.index_txt_width, self.index_txt_height = self.get_txt_dimensions("|", self.PAR.ops.index_font)
|
4136
|
+
self.min_row_height = max(6, self.table_txt_height, self.index_txt_height) + 6
|
3980
4137
|
|
3981
|
-
def
|
3982
|
-
|
3983
|
-
|
3984
|
-
|
3985
|
-
|
3986
|
-
|
3987
|
-
|
3988
|
-
|
3989
|
-
|
4138
|
+
def change_font_manage_row_heights(self, old_min_row_height: int, old_default_row_height: int) -> None:
|
4139
|
+
default_row_height = self.get_default_row_height()
|
4140
|
+
self.row_positions = list(
|
4141
|
+
accumulate(
|
4142
|
+
chain(
|
4143
|
+
[0],
|
4144
|
+
(
|
4145
|
+
(
|
4146
|
+
self.min_row_height
|
4147
|
+
if h == old_min_row_height
|
4148
|
+
else (
|
4149
|
+
default_row_height
|
4150
|
+
if h == old_default_row_height
|
4151
|
+
else self.min_row_height
|
4152
|
+
if h < self.min_row_height
|
4153
|
+
else h
|
4154
|
+
)
|
4155
|
+
)
|
4156
|
+
for h in self.gen_row_heights()
|
4157
|
+
),
|
3990
4158
|
)
|
3991
|
-
|
3992
|
-
|
3993
|
-
return self.PAR.ops.index_font
|
4159
|
+
)
|
4160
|
+
)
|
3994
4161
|
|
3995
|
-
def
|
3996
|
-
|
3997
|
-
|
3998
|
-
|
3999
|
-
self.
|
4000
|
-
|
4001
|
-
|
4002
|
-
|
4003
|
-
|
4162
|
+
def set_header_font(self, newfont: tuple | None = None) -> tuple[str, int, str]:
|
4163
|
+
if newfont:
|
4164
|
+
self.check_font(newfont)
|
4165
|
+
self.PAR.ops.header_font = FontTuple(*newfont)
|
4166
|
+
self.set_header_font_help()
|
4167
|
+
self.recreate_all_selection_boxes()
|
4168
|
+
return self.PAR.ops.header_font
|
4169
|
+
|
4170
|
+
def set_header_font_help(self):
|
4171
|
+
self.CH.header_font = self.PAR.ops.header_font
|
4172
|
+
if self.PAR.ops.header_font not in self.char_widths:
|
4173
|
+
self.char_widths[self.PAR.ops.header_font] = {}
|
4174
|
+
self.CH.header_test_str_w = self.get_txt_w(_test_str, self.PAR.ops.header_font)
|
4175
|
+
self.header_txt_width, self.header_txt_height = self.get_txt_dimensions("|", self.PAR.ops.header_font)
|
4176
|
+
self.min_header_height = self.header_txt_height + 6
|
4177
|
+
if (
|
4178
|
+
isinstance(self.PAR.ops.default_header_height, int)
|
4179
|
+
and self.PAR.ops.default_header_height < self.min_header_height
|
4180
|
+
):
|
4181
|
+
self.PAR.ops.default_header_height = int(self.min_header_height)
|
4182
|
+
self.CH.set_height(self.get_default_header_height(), set_TL=True)
|
4004
4183
|
|
4005
4184
|
def purge_undo_and_redo_stack(self):
|
4006
4185
|
self.undo_stack = deque(maxlen=self.PAR.ops.max_undos)
|
@@ -4123,6 +4302,58 @@ class MainTable(tk.Canvas):
|
|
4123
4302
|
else:
|
4124
4303
|
return False
|
4125
4304
|
|
4305
|
+
def get_cell_max_width(self, datarn: int, dispcn: int) -> int:
|
4306
|
+
datacn = self.datacn(dispcn)
|
4307
|
+
col_width = self.col_positions[dispcn + 1] - self.col_positions[dispcn]
|
4308
|
+
if kwargs := self.get_cell_kwargs(datarn, datacn, "dropdown"):
|
4309
|
+
max_width = col_width - self.table_txt_height - 5
|
4310
|
+
else:
|
4311
|
+
max_width = col_width - 2
|
4312
|
+
if (kwargs := self.get_cell_kwargs(datarn, datacn, "dropdown")) and max_width > self.table_txt_height + 1:
|
4313
|
+
box_w = self.table_txt_height + 1
|
4314
|
+
max_width -= box_w + 4
|
4315
|
+
if self.PAR.ops.allow_cell_overflow and not kwargs:
|
4316
|
+
if self.cells_cache is None:
|
4317
|
+
disprn = self.disprn(datarn)
|
4318
|
+
self.cells_cache = self._redraw_precache_cells(disprn, disprn + 1, 0, len(self.col_positions) - 1)
|
4319
|
+
if not (align := self.get_cell_kwargs(datarn, datacn, key="align")):
|
4320
|
+
align = self.align
|
4321
|
+
if align.endswith("w"):
|
4322
|
+
max_width += sum(
|
4323
|
+
self._overflow(
|
4324
|
+
self.cells_cache,
|
4325
|
+
range(dispcn + 1, len(self.col_positions) - 1),
|
4326
|
+
datarn,
|
4327
|
+
)
|
4328
|
+
)
|
4329
|
+
elif align.endswith("e"):
|
4330
|
+
max_width += sum(
|
4331
|
+
self._overflow(
|
4332
|
+
self.cells_cache,
|
4333
|
+
reversed(range(0, dispcn)),
|
4334
|
+
datarn,
|
4335
|
+
)
|
4336
|
+
)
|
4337
|
+
return max_width
|
4338
|
+
|
4339
|
+
def get_wrapped_cell_height(self, datarn: int, datacn: int) -> int:
|
4340
|
+
dispcn = self.dispcn(datacn)
|
4341
|
+
n_lines = max(
|
4342
|
+
1,
|
4343
|
+
sum(
|
4344
|
+
1
|
4345
|
+
for _ in wrap_text(
|
4346
|
+
text=self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True),
|
4347
|
+
max_width=self.get_cell_max_width(datarn, dispcn),
|
4348
|
+
max_lines=float("inf"),
|
4349
|
+
char_width_fn=self.wrap_get_char_w,
|
4350
|
+
widths=self.char_widths[self.table_font],
|
4351
|
+
wrap=self.PAR.ops.table_wrap,
|
4352
|
+
)
|
4353
|
+
),
|
4354
|
+
)
|
4355
|
+
return 3 + (n_lines * self.table_txt_height)
|
4356
|
+
|
4126
4357
|
def set_all_cell_sizes_to_text(
|
4127
4358
|
self,
|
4128
4359
|
width: int | None = None,
|
@@ -4206,26 +4437,28 @@ class MainTable(tk.Canvas):
|
|
4206
4437
|
def set_col_positions(self, itr: AnyIter[float]) -> None:
|
4207
4438
|
self.col_positions = list(accumulate(chain([0], itr)))
|
4208
4439
|
|
4209
|
-
def reset_col_positions(self, ncols: int | None = None):
|
4210
|
-
|
4440
|
+
def reset_col_positions(self, ncols: int | None = None, width: int | None = None) -> None:
|
4441
|
+
if width is None:
|
4442
|
+
width = self.PAR.ops.default_column_width
|
4211
4443
|
if isinstance(ncols, int):
|
4212
|
-
self.set_col_positions(itr=repeat(
|
4444
|
+
self.set_col_positions(itr=repeat(width, ncols))
|
4213
4445
|
elif self.all_columns_displayed:
|
4214
|
-
self.set_col_positions(itr=repeat(
|
4446
|
+
self.set_col_positions(itr=repeat(width, self.total_data_cols()))
|
4215
4447
|
else:
|
4216
|
-
self.set_col_positions(itr=repeat(
|
4448
|
+
self.set_col_positions(itr=repeat(width, len(self.displayed_columns)))
|
4217
4449
|
|
4218
4450
|
def set_row_positions(self, itr: AnyIter[float]) -> None:
|
4219
4451
|
self.row_positions = list(accumulate(chain([0], itr)))
|
4220
4452
|
|
4221
|
-
def reset_row_positions(self, nrows: int | None = None):
|
4222
|
-
|
4453
|
+
def reset_row_positions(self, nrows: int | None = None, height: int | None = None) -> None:
|
4454
|
+
if height is None:
|
4455
|
+
height = self.get_default_row_height()
|
4223
4456
|
if isinstance(nrows, int):
|
4224
|
-
self.set_row_positions(itr=repeat(
|
4457
|
+
self.set_row_positions(itr=repeat(height, nrows))
|
4225
4458
|
elif self.all_rows_displayed:
|
4226
|
-
self.set_row_positions(itr=repeat(
|
4459
|
+
self.set_row_positions(itr=repeat(height, self.total_data_rows()))
|
4227
4460
|
else:
|
4228
|
-
self.set_row_positions(itr=repeat(
|
4461
|
+
self.set_row_positions(itr=repeat(height, len(self.displayed_rows)))
|
4229
4462
|
|
4230
4463
|
def del_col_position(self, idx: int, deselect_all: bool = False):
|
4231
4464
|
if deselect_all:
|
@@ -4277,46 +4510,6 @@ class MainTable(tk.Canvas):
|
|
4277
4510
|
def gen_row_heights(self) -> Generator[int]:
|
4278
4511
|
return diff_gen(self.row_positions)
|
4279
4512
|
|
4280
|
-
def insert_col_position(
|
4281
|
-
self,
|
4282
|
-
idx: Literal["end"] | int = "end",
|
4283
|
-
width: int | None = None,
|
4284
|
-
deselect_all: bool = False,
|
4285
|
-
) -> None:
|
4286
|
-
if deselect_all:
|
4287
|
-
self.deselect("all", redraw=False)
|
4288
|
-
if width is None:
|
4289
|
-
w = self.PAR.ops.default_column_width
|
4290
|
-
else:
|
4291
|
-
w = width
|
4292
|
-
if idx == "end" or len(self.col_positions) == idx + 1:
|
4293
|
-
self.col_positions.append(self.col_positions[-1] + w)
|
4294
|
-
else:
|
4295
|
-
idx += 1
|
4296
|
-
self.col_positions.insert(idx, self.col_positions[idx - 1] + w)
|
4297
|
-
idx += 1
|
4298
|
-
self.col_positions[idx:] = [e + w for e in islice(self.col_positions, idx, len(self.col_positions))]
|
4299
|
-
|
4300
|
-
def insert_row_position(
|
4301
|
-
self,
|
4302
|
-
idx: Literal["end"] | int = "end",
|
4303
|
-
height: int | None = None,
|
4304
|
-
deselect_all: bool = False,
|
4305
|
-
) -> None:
|
4306
|
-
if deselect_all:
|
4307
|
-
self.deselect("all", redraw=False)
|
4308
|
-
if height is None:
|
4309
|
-
h = self.get_default_row_height()
|
4310
|
-
else:
|
4311
|
-
h = height
|
4312
|
-
if idx == "end" or len(self.row_positions) == idx + 1:
|
4313
|
-
self.row_positions.append(self.row_positions[-1] + h)
|
4314
|
-
else:
|
4315
|
-
idx += 1
|
4316
|
-
self.row_positions.insert(idx, self.row_positions[idx - 1] + h)
|
4317
|
-
idx += 1
|
4318
|
-
self.row_positions[idx:] = [e + h for e in islice(self.row_positions, idx, len(self.row_positions))]
|
4319
|
-
|
4320
4513
|
def insert_col_positions(
|
4321
4514
|
self,
|
4322
4515
|
idx: Literal["end"] | int = "end",
|
@@ -4403,25 +4596,13 @@ class MainTable(tk.Canvas):
|
|
4403
4596
|
create_ops: bool = True,
|
4404
4597
|
) -> None:
|
4405
4598
|
self.tagged_cells = {
|
4406
|
-
tags: {(r, c
|
4407
|
-
for tags, tagged in self.tagged_cells.items()
|
4408
|
-
}
|
4409
|
-
self.cell_options = {
|
4410
|
-
(r, c if not (num := bisect_right(cols, c)) else c + num): v for (r, c), v in self.cell_options.items()
|
4411
|
-
}
|
4412
|
-
self.progress_bars = {
|
4413
|
-
(r, c if not (num := bisect_right(cols, c)) else c + num): v for (r, c), v in self.progress_bars.items()
|
4414
|
-
}
|
4415
|
-
self.tagged_columns = {
|
4416
|
-
tags: {c if not (num := bisect_right(cols, c)) else c + num for c in tagged}
|
4417
|
-
for tags, tagged in self.tagged_columns.items()
|
4418
|
-
}
|
4419
|
-
self.col_options = {
|
4420
|
-
c if not (num := bisect_right(cols, c)) else c + num: v for c, v in self.col_options.items()
|
4421
|
-
}
|
4422
|
-
self.CH.cell_options = {
|
4423
|
-
c if not (num := bisect_right(cols, c)) else c + num: v for c, v in self.CH.cell_options.items()
|
4599
|
+
tags: {(r, push_n(c, cols)) for (r, c) in tagged} for tags, tagged in self.tagged_cells.items()
|
4424
4600
|
}
|
4601
|
+
self.cell_options = {(r, push_n(c, cols)): v for (r, c), v in self.cell_options.items()}
|
4602
|
+
self.progress_bars = {(r, push_n(c, cols)): v for (r, c), v in self.progress_bars.items()}
|
4603
|
+
self.tagged_columns = {tags: {push_n(c, cols) for c in tagged} for tags, tagged in self.tagged_columns.items()}
|
4604
|
+
self.col_options = {push_n(c, cols): v for c, v in self.col_options.items()}
|
4605
|
+
self.CH.cell_options = {push_n(c, cols): v for c, v in self.CH.cell_options.items()}
|
4425
4606
|
# if there are named spans where columns were added
|
4426
4607
|
# add options to gap which was created by adding columns
|
4427
4608
|
totalrows = None
|
@@ -4471,32 +4652,18 @@ class MainTable(tk.Canvas):
|
|
4471
4652
|
|
4472
4653
|
def adjust_options_post_add_rows(
|
4473
4654
|
self,
|
4474
|
-
rows: list | tuple,
|
4655
|
+
rows: list[int] | tuple[int],
|
4475
4656
|
create_ops: bool = True,
|
4476
4657
|
) -> None:
|
4477
4658
|
self.tagged_cells = {
|
4478
|
-
tags: {(r
|
4479
|
-
for tags, tagged in self.tagged_cells.items()
|
4480
|
-
}
|
4481
|
-
self.cell_options = {
|
4482
|
-
(r if not (num := bisect_right(rows, r)) else r + num, c): v for (r, c), v in self.cell_options.items()
|
4483
|
-
}
|
4484
|
-
self.progress_bars = {
|
4485
|
-
(r if not (num := bisect_right(rows, r)) else r + num, c): v for (r, c), v in self.progress_bars.items()
|
4486
|
-
}
|
4487
|
-
self.tagged_rows = {
|
4488
|
-
tags: {r if not (num := bisect_right(rows, r)) else r + num for r in tagged}
|
4489
|
-
for tags, tagged in self.tagged_rows.items()
|
4490
|
-
}
|
4491
|
-
self.row_options = {
|
4492
|
-
r if not (num := bisect_right(rows, r)) else r + num: v for r, v in self.row_options.items()
|
4493
|
-
}
|
4494
|
-
self.RI.cell_options = {
|
4495
|
-
r if not (num := bisect_right(rows, r)) else r + num: v for r, v in self.RI.cell_options.items()
|
4496
|
-
}
|
4497
|
-
self.RI.tree_rns = {
|
4498
|
-
v: r if not (num := bisect_right(rows, r)) else r + num for v, r in self.RI.tree_rns.items()
|
4659
|
+
tags: {(push_n(r, rows), c) for (r, c) in tagged} for tags, tagged in self.tagged_cells.items()
|
4499
4660
|
}
|
4661
|
+
self.cell_options = {(push_n(r, rows), c): v for (r, c), v in self.cell_options.items()}
|
4662
|
+
self.progress_bars = {(push_n(r, rows), c): v for (r, c), v in self.progress_bars.items()}
|
4663
|
+
self.tagged_rows = {tags: {push_n(r, rows) for r in tagged} for tags, tagged in self.tagged_rows.items()}
|
4664
|
+
self.row_options = {push_n(r, rows): v for r, v in self.row_options.items()}
|
4665
|
+
self.RI.cell_options = {push_n(r, rows): v for r, v in self.RI.cell_options.items()}
|
4666
|
+
self.RI.tree_rns = {k: push_n(r, rows) for k, r in self.RI.tree_rns.items()}
|
4500
4667
|
# if there are named spans where rows were added
|
4501
4668
|
# add options to gap which was created by adding rows
|
4502
4669
|
totalcols = None
|
@@ -4731,29 +4898,27 @@ class MainTable(tk.Canvas):
|
|
4731
4898
|
header: dict,
|
4732
4899
|
column_widths: dict,
|
4733
4900
|
event_data: dict,
|
4734
|
-
displayed_columns: None | list[int] = None,
|
4735
4901
|
create_ops: bool = True,
|
4736
4902
|
create_selections: bool = True,
|
4737
4903
|
add_row_positions: bool = True,
|
4738
4904
|
push_ops: bool = True,
|
4739
4905
|
mod_event_boxes: bool = True,
|
4906
|
+
restored_state: bool = False,
|
4740
4907
|
) -> EventDataDict:
|
4741
4908
|
self.saved_column_widths = {}
|
4742
|
-
|
4743
|
-
if isinstance(displayed_columns, list):
|
4744
|
-
self.displayed_columns = displayed_columns
|
4745
|
-
elif not self.all_columns_displayed:
|
4909
|
+
if not restored_state and not self.all_columns_displayed:
|
4746
4910
|
self.displayed_columns = add_to_displayed(self.displayed_columns, columns)
|
4747
4911
|
cws = self.get_column_widths()
|
4748
4912
|
if column_widths and next(reversed(column_widths)) > len(cws):
|
4749
4913
|
for i in reversed(range(len(cws), len(cws) + next(reversed(column_widths)) - len(cws))):
|
4750
4914
|
column_widths[i] = self.PAR.ops.default_column_width
|
4751
|
-
|
4752
|
-
|
4753
|
-
|
4754
|
-
|
4915
|
+
if not restored_state:
|
4916
|
+
self.set_col_positions(
|
4917
|
+
itr=insert_items(
|
4918
|
+
cws,
|
4919
|
+
column_widths,
|
4920
|
+
)
|
4755
4921
|
)
|
4756
|
-
)
|
4757
4922
|
# rn needed for indexing but cn insert
|
4758
4923
|
maxrn = 0
|
4759
4924
|
for cn, rowdict in reversed(columns.items()):
|
@@ -4772,14 +4937,14 @@ class MainTable(tk.Canvas):
|
|
4772
4937
|
"table": {},
|
4773
4938
|
"index": {},
|
4774
4939
|
"row_heights": {rn: default_height for rn in range(len(self.row_positions) - 1, maxrn + 1)},
|
4775
|
-
"displayed_rows": self.displayed_rows,
|
4776
4940
|
}
|
4777
|
-
|
4778
|
-
|
4779
|
-
|
4780
|
-
|
4941
|
+
if not restored_state:
|
4942
|
+
self.set_row_positions(
|
4943
|
+
itr=chain(
|
4944
|
+
self.gen_row_heights(),
|
4945
|
+
repeat(default_height, maxrn + 1 - (len(self.row_positions) - 1)),
|
4946
|
+
)
|
4781
4947
|
)
|
4782
|
-
)
|
4783
4948
|
if isinstance(self._headers, list) and header:
|
4784
4949
|
self._headers = insert_items(self._headers, header, self.CH.fix_header)
|
4785
4950
|
if push_ops:
|
@@ -4805,7 +4970,6 @@ class MainTable(tk.Canvas):
|
|
4805
4970
|
"table": columns,
|
4806
4971
|
"header": header,
|
4807
4972
|
"column_widths": column_widths,
|
4808
|
-
"displayed_columns": saved_displayed_columns,
|
4809
4973
|
}
|
4810
4974
|
return event_data
|
4811
4975
|
|
@@ -4842,13 +5006,7 @@ class MainTable(tk.Canvas):
|
|
4842
5006
|
numcols = self.PAR.ops.paste_insert_column_limit - len(self.col_positions) - 1
|
4843
5007
|
if numcols < 1:
|
4844
5008
|
return
|
4845
|
-
event_data =
|
4846
|
-
name="add_columns",
|
4847
|
-
sheet=self.PAR.name,
|
4848
|
-
widget=self,
|
4849
|
-
boxes=self.get_boxes(),
|
4850
|
-
selected=self.selected,
|
4851
|
-
)
|
5009
|
+
event_data = self.new_event_dict("add_columns", state=True)
|
4852
5010
|
if not try_binding(self.extra_begin_insert_cols_rc_func, event_data, "begin_add_columns"):
|
4853
5011
|
return
|
4854
5012
|
event_data = self.add_columns(
|
@@ -4863,34 +5021,33 @@ class MainTable(tk.Canvas):
|
|
4863
5021
|
|
4864
5022
|
def add_rows(
|
4865
5023
|
self,
|
4866
|
-
rows: dict,
|
4867
|
-
index: dict,
|
4868
|
-
row_heights: dict,
|
4869
|
-
event_data:
|
4870
|
-
displayed_rows: None | list[int] = None,
|
5024
|
+
rows: dict[int, list[object]],
|
5025
|
+
index: dict[int, object],
|
5026
|
+
row_heights: dict[int, float | int],
|
5027
|
+
event_data: EventDataDict,
|
4871
5028
|
create_ops: bool = True,
|
4872
5029
|
create_selections: bool = True,
|
4873
5030
|
add_col_positions: bool = True,
|
4874
5031
|
push_ops: bool = True,
|
5032
|
+
tree: bool = True,
|
4875
5033
|
mod_event_boxes: bool = True,
|
5034
|
+
restored_state: bool = False,
|
4876
5035
|
) -> EventDataDict:
|
4877
5036
|
self.saved_row_heights = {}
|
4878
|
-
|
4879
|
-
if isinstance(displayed_rows, list):
|
4880
|
-
self.displayed_rows = displayed_rows
|
4881
|
-
elif not self.all_rows_displayed:
|
5037
|
+
if not restored_state and not self.all_rows_displayed:
|
4882
5038
|
self.displayed_rows = add_to_displayed(self.displayed_rows, rows)
|
4883
5039
|
rhs = self.get_row_heights()
|
4884
5040
|
if row_heights and next(reversed(row_heights)) > len(rhs):
|
4885
5041
|
default_row_height = self.get_default_row_height()
|
4886
5042
|
for i in reversed(range(len(rhs), len(rhs) + next(reversed(row_heights)) - len(rhs))):
|
4887
5043
|
row_heights[i] = default_row_height
|
4888
|
-
|
4889
|
-
|
4890
|
-
|
4891
|
-
|
5044
|
+
if not restored_state:
|
5045
|
+
self.set_row_positions(
|
5046
|
+
itr=insert_items(
|
5047
|
+
rhs,
|
5048
|
+
row_heights,
|
5049
|
+
)
|
4892
5050
|
)
|
4893
|
-
)
|
4894
5051
|
maxcn = 0
|
4895
5052
|
# rn needed for insert but cn indexing
|
4896
5053
|
for rn, row in reversed(rows.items()):
|
@@ -4909,14 +5066,14 @@ class MainTable(tk.Canvas):
|
|
4909
5066
|
"table": {},
|
4910
5067
|
"header": {},
|
4911
5068
|
"column_widths": {cn: default_width for cn in range(len(self.col_positions) - 1, maxcn + 1)},
|
4912
|
-
"displayed_columns": self.displayed_columns,
|
4913
5069
|
}
|
4914
|
-
|
4915
|
-
|
4916
|
-
|
4917
|
-
|
5070
|
+
if not restored_state:
|
5071
|
+
self.set_col_positions(
|
5072
|
+
itr=chain(
|
5073
|
+
self.gen_column_widths(),
|
5074
|
+
repeat(default_width, maxcn + 1 - (len(self.col_positions) - 1)),
|
5075
|
+
)
|
4918
5076
|
)
|
4919
|
-
)
|
4920
5077
|
if push_ops:
|
4921
5078
|
self.adjust_options_post_add_rows(
|
4922
5079
|
rows=tuple(reversed(rows)),
|
@@ -4940,8 +5097,9 @@ class MainTable(tk.Canvas):
|
|
4940
5097
|
"table": rows,
|
4941
5098
|
"index": index,
|
4942
5099
|
"row_heights": row_heights,
|
4943
|
-
"displayed_rows": saved_displayed_rows,
|
4944
5100
|
}
|
5101
|
+
if tree and self.PAR.ops.treeview:
|
5102
|
+
event_data = self.RI.tree_add_rows(event_data=event_data)
|
4945
5103
|
return event_data
|
4946
5104
|
|
4947
5105
|
def rc_add_rows(self, event: object = None):
|
@@ -4977,13 +5135,7 @@ class MainTable(tk.Canvas):
|
|
4977
5135
|
numrows = self.PAR.ops.paste_insert_row_limit - len(self.row_positions) - 1
|
4978
5136
|
if numrows < 1:
|
4979
5137
|
return
|
4980
|
-
event_data =
|
4981
|
-
name="add_rows",
|
4982
|
-
sheet=self.PAR.name,
|
4983
|
-
widget=self,
|
4984
|
-
boxes=self.get_boxes(),
|
4985
|
-
selected=self.selected,
|
4986
|
-
)
|
5138
|
+
event_data = self.new_event_dict("add_rows", state=True)
|
4987
5139
|
if not try_binding(self.extra_begin_insert_rows_rc_func, event_data, "begin_add_rows"):
|
4988
5140
|
return
|
4989
5141
|
event_data = self.add_rows(
|
@@ -5064,10 +5216,14 @@ class MainTable(tk.Canvas):
|
|
5064
5216
|
for datarn, v in zip(reversed(range(data_ins_row, data_ins_row + numrows)), reversed(rows))
|
5065
5217
|
}
|
5066
5218
|
else:
|
5067
|
-
|
5068
|
-
|
5069
|
-
|
5070
|
-
|
5219
|
+
if self.PAR.ops.treeview:
|
5220
|
+
nodes = [self.RI.get_value_for_empty_cell(data_ins_row, r_ops=False) for _ in range(numrows)]
|
5221
|
+
index_data = dict(zip(reversed(range(data_ins_row, data_ins_row + numrows)), reversed(nodes)))
|
5222
|
+
else:
|
5223
|
+
index_data = {
|
5224
|
+
datarn: self.RI.get_value_for_empty_cell(datarn, r_ops=False)
|
5225
|
+
for datarn in reversed(range(data_ins_row, data_ins_row + numrows))
|
5226
|
+
}
|
5071
5227
|
if rows is None:
|
5072
5228
|
if total_data_cols is None:
|
5073
5229
|
total_data_cols = self.total_data_cols()
|
@@ -5107,11 +5263,27 @@ class MainTable(tk.Canvas):
|
|
5107
5263
|
"tagged_columns": {f"{tag}": set(s) for tag, s in self.tagged_columns.items()},
|
5108
5264
|
}
|
5109
5265
|
|
5110
|
-
def
|
5266
|
+
def copy_sheet_state(self) -> dict:
|
5267
|
+
return {
|
5268
|
+
"row_positions": list(self.row_positions),
|
5269
|
+
"col_positions": list(self.col_positions),
|
5270
|
+
"displayed_rows": int(self.displayed_rows)
|
5271
|
+
if isinstance(self.displayed_rows, int)
|
5272
|
+
else list(self.displayed_rows),
|
5273
|
+
"displayed_columns": int(self.displayed_columns)
|
5274
|
+
if isinstance(self.displayed_columns, int)
|
5275
|
+
else list(self.displayed_columns),
|
5276
|
+
"all_rows_displayed": bool(self.all_rows_displayed),
|
5277
|
+
"saved_row_heights": dict(self.saved_row_heights),
|
5278
|
+
"saved_column_widths": dict(self.saved_column_widths),
|
5279
|
+
"all_columns_displayed": bool(self.all_columns_displayed),
|
5280
|
+
"tree_open_ids": set(self.RI.tree_open_ids),
|
5281
|
+
}
|
5282
|
+
|
5283
|
+
def delete_columns_data(self, cols: list[int], event_data: EventDataDict | None = None) -> EventDataDict:
|
5111
5284
|
self.mouseclick_outside_editor_or_dropdown_all_canvases()
|
5112
|
-
|
5113
|
-
|
5114
|
-
)
|
5285
|
+
if not event_data:
|
5286
|
+
event_data = self.new_event_dict("delete_columns", state=True)
|
5115
5287
|
event_data["options"] = self.copy_options()
|
5116
5288
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
5117
5289
|
for datacn in reversed(cols):
|
@@ -5139,41 +5311,62 @@ class MainTable(tk.Canvas):
|
|
5139
5311
|
]
|
5140
5312
|
return event_data
|
5141
5313
|
|
5142
|
-
def delete_columns_displayed(
|
5314
|
+
def delete_columns_displayed(
|
5315
|
+
self,
|
5316
|
+
cols: list[int],
|
5317
|
+
event_data: EventDataDict | None = None,
|
5318
|
+
restored_state: bool = False,
|
5319
|
+
) -> EventDataDict:
|
5320
|
+
if not event_data:
|
5321
|
+
event_data = self.new_event_dict("delete_columns", state=True)
|
5143
5322
|
self.saved_column_widths = {}
|
5144
|
-
|
5145
|
-
|
5146
|
-
|
5147
|
-
|
5323
|
+
if cols:
|
5324
|
+
for c in reversed(cols):
|
5325
|
+
if len(self.col_positions) > c + 1:
|
5326
|
+
event_data["deleted"]["column_widths"][c] = self.col_positions[c + 1] - self.col_positions[c]
|
5327
|
+
if not restored_state:
|
5328
|
+
cols_set = set(cols)
|
5329
|
+
self.set_col_positions(
|
5330
|
+
itr=(width for c, width in enumerate(self.gen_column_widths()) if c not in cols_set)
|
5331
|
+
)
|
5148
5332
|
return event_data
|
5149
5333
|
|
5150
|
-
def
|
5151
|
-
|
5152
|
-
|
5334
|
+
def delete_columns(
|
5335
|
+
self,
|
5336
|
+
event: object = None,
|
5337
|
+
columns: list[int] | None = None,
|
5338
|
+
data_indexes: bool = False,
|
5339
|
+
undo: bool = True,
|
5340
|
+
emit_event: bool = True,
|
5341
|
+
ext: bool = False,
|
5342
|
+
) -> EventDataDict:
|
5343
|
+
event_data = self.new_event_dict("delete_columns", state=True)
|
5344
|
+
if not columns:
|
5345
|
+
if not (columns := sorted(self.get_selected_cols())):
|
5346
|
+
return event_data
|
5347
|
+
if not ext and not try_binding(self.extra_begin_del_cols_rc_func, event_data, "begin_delete_columns"):
|
5153
5348
|
return
|
5154
|
-
event_data =
|
5155
|
-
|
5156
|
-
|
5157
|
-
widget=self,
|
5158
|
-
boxes=self.get_boxes(),
|
5159
|
-
selected=self.selected,
|
5349
|
+
event_data = self.delete_columns_displayed(
|
5350
|
+
data_to_displayed_idxs(columns, self.MT.displayed_columns) if data_indexes else columns,
|
5351
|
+
event_data,
|
5160
5352
|
)
|
5161
|
-
|
5162
|
-
|
5163
|
-
|
5164
|
-
|
5165
|
-
|
5166
|
-
if self.undo_enabled:
|
5353
|
+
event_data = self.delete_columns_data(
|
5354
|
+
columns if data_indexes or self.all_columns_displayed else [self.displayed_columns[c] for c in columns],
|
5355
|
+
event_data,
|
5356
|
+
)
|
5357
|
+
if undo and self.undo_enabled:
|
5167
5358
|
self.undo_stack.append(stored_event_dict(event_data))
|
5359
|
+
if not ext:
|
5360
|
+
try_binding(self.extra_end_del_cols_rc_func, event_data, "end_delete_columns")
|
5361
|
+
if emit_event:
|
5362
|
+
self.sheet_modified(event_data)
|
5168
5363
|
self.deselect("all")
|
5169
|
-
|
5170
|
-
self.sheet_modified(event_data)
|
5364
|
+
return event_data
|
5171
5365
|
|
5172
|
-
def delete_rows_data(self, rows: list, event_data:
|
5366
|
+
def delete_rows_data(self, rows: list[int], event_data: EventDataDict | None = None) -> EventDataDict:
|
5173
5367
|
self.mouseclick_outside_editor_or_dropdown_all_canvases()
|
5174
|
-
|
5175
|
-
|
5176
|
-
)
|
5368
|
+
if not event_data:
|
5369
|
+
event_data = self.new_event_dict("delete_rows", state=True)
|
5177
5370
|
event_data["options"] = self.copy_options()
|
5178
5371
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
5179
5372
|
for datarn in reversed(rows):
|
@@ -5182,6 +5375,8 @@ class MainTable(tk.Canvas):
|
|
5182
5375
|
event_data["deleted"]["index"][datarn] = self._row_index.pop(datarn)
|
5183
5376
|
except Exception:
|
5184
5377
|
continue
|
5378
|
+
if self.PAR.ops.treeview:
|
5379
|
+
event_data = self.RI.tree_del_rows(event_data=event_data)
|
5185
5380
|
rows_set = set(rows)
|
5186
5381
|
self.adjust_options_post_delete_rows(
|
5187
5382
|
to_del=rows_set,
|
@@ -5195,35 +5390,72 @@ class MainTable(tk.Canvas):
|
|
5195
5390
|
]
|
5196
5391
|
return event_data
|
5197
5392
|
|
5198
|
-
def delete_rows_displayed(
|
5393
|
+
def delete_rows_displayed(
|
5394
|
+
self,
|
5395
|
+
rows: list[int],
|
5396
|
+
event_data: EventDataDict | None = None,
|
5397
|
+
restored_state: bool = False,
|
5398
|
+
) -> EventDataDict:
|
5399
|
+
if not event_data:
|
5400
|
+
event_data = self.new_event_dict("delete_rows", state=True)
|
5199
5401
|
self.saved_row_heights = {}
|
5200
|
-
|
5201
|
-
|
5202
|
-
|
5203
|
-
|
5402
|
+
if rows:
|
5403
|
+
for r in reversed(rows):
|
5404
|
+
if len(self.row_positions) > r + 1:
|
5405
|
+
event_data["deleted"]["row_heights"][r] = self.row_positions[r + 1] - self.row_positions[r]
|
5406
|
+
if not restored_state:
|
5407
|
+
rows_set = set(rows)
|
5408
|
+
self.set_row_positions(
|
5409
|
+
itr=(height for r, height in enumerate(self.gen_row_heights()) if r not in rows_set)
|
5410
|
+
)
|
5204
5411
|
return event_data
|
5205
5412
|
|
5206
|
-
def
|
5207
|
-
|
5208
|
-
|
5413
|
+
def delete_rows(
|
5414
|
+
self,
|
5415
|
+
event: object = None,
|
5416
|
+
rows: list[int] | None = None,
|
5417
|
+
data_indexes: bool = False,
|
5418
|
+
undo: bool = True,
|
5419
|
+
emit_event: bool = True,
|
5420
|
+
ext: bool = False,
|
5421
|
+
) -> EventDataDict:
|
5422
|
+
event_data = self.new_event_dict("delete_rows", state=True)
|
5423
|
+
if not rows:
|
5424
|
+
if not (rows := sorted(self.get_selected_rows())):
|
5425
|
+
return
|
5426
|
+
if not ext and not try_binding(self.extra_begin_del_rows_rc_func, event_data, "begin_delete_rows"):
|
5209
5427
|
return
|
5210
|
-
|
5211
|
-
|
5212
|
-
|
5213
|
-
|
5214
|
-
|
5215
|
-
|
5428
|
+
if data_indexes or self.all_rows_displayed:
|
5429
|
+
data_rows = rows
|
5430
|
+
else:
|
5431
|
+
data_rows = [self.displayed_rows[r] for r in rows]
|
5432
|
+
if self.PAR.ops.treeview:
|
5433
|
+
data_rows = sorted(
|
5434
|
+
chain(
|
5435
|
+
data_rows,
|
5436
|
+
(
|
5437
|
+
self.RI.tree_rns[did]
|
5438
|
+
for r in data_rows
|
5439
|
+
for did in self.RI.get_iid_descendants(self._row_index[r].iid)
|
5440
|
+
),
|
5441
|
+
)
|
5442
|
+
)
|
5443
|
+
event_data = self.delete_rows_displayed(
|
5444
|
+
data_to_displayed_idxs(data_rows, self.displayed_rows) if self.PAR.ops.treeview or data_indexes else rows,
|
5445
|
+
event_data,
|
5216
5446
|
)
|
5217
|
-
|
5218
|
-
|
5219
|
-
|
5220
|
-
|
5221
|
-
|
5222
|
-
if self.undo_enabled:
|
5447
|
+
event_data = self.delete_rows_data(
|
5448
|
+
data_rows,
|
5449
|
+
event_data,
|
5450
|
+
)
|
5451
|
+
if undo and self.undo_enabled:
|
5223
5452
|
self.undo_stack.append(stored_event_dict(event_data))
|
5453
|
+
if not ext:
|
5454
|
+
try_binding(self.extra_end_del_rows_rc_func, event_data, "end_delete_rows")
|
5455
|
+
if emit_event:
|
5456
|
+
self.sheet_modified(event_data)
|
5224
5457
|
self.deselect("all")
|
5225
|
-
|
5226
|
-
self.sheet_modified(event_data)
|
5458
|
+
return event_data
|
5227
5459
|
|
5228
5460
|
def move_row_position(self, idx1: int, idx2: int):
|
5229
5461
|
if not len(self.row_positions) <= 2:
|
@@ -5495,7 +5727,7 @@ class MainTable(tk.Canvas):
|
|
5495
5727
|
can_width: int | None,
|
5496
5728
|
dont_blend: bool,
|
5497
5729
|
alternate_color: Highlight | None,
|
5498
|
-
) -> str:
|
5730
|
+
) -> tuple[str, bool]:
|
5499
5731
|
redrawn = False
|
5500
5732
|
if (datarn, datacn) in self.progress_bars:
|
5501
5733
|
kwargs = self.progress_bars[(datarn, datacn)]
|
@@ -5574,7 +5806,6 @@ class MainTable(tk.Canvas):
|
|
5574
5806
|
if self.get_cell_kwargs(datarn, datacn, key="dropdown") and self.PAR.ops.show_dropdown_borders
|
5575
5807
|
else ""
|
5576
5808
|
),
|
5577
|
-
tag="hi",
|
5578
5809
|
)
|
5579
5810
|
if isinstance(kwargs, ProgressBar):
|
5580
5811
|
if kwargs.del_when_done and kwargs.percent >= 100:
|
@@ -5600,7 +5831,17 @@ class MainTable(tk.Canvas):
|
|
5600
5831
|
txtfg = self.PAR.ops.table_fg
|
5601
5832
|
return txtfg, redrawn
|
5602
5833
|
|
5603
|
-
def redraw_highlight(
|
5834
|
+
def redraw_highlight(
|
5835
|
+
self,
|
5836
|
+
x1: int | float,
|
5837
|
+
y1: int | float,
|
5838
|
+
x2: int | float,
|
5839
|
+
y2: int | float,
|
5840
|
+
fill: str,
|
5841
|
+
outline: str,
|
5842
|
+
can_width: None | float = None,
|
5843
|
+
pc: None | float = None,
|
5844
|
+
) -> bool:
|
5604
5845
|
if not is_type_int(pc) or pc >= 100:
|
5605
5846
|
coords = (
|
5606
5847
|
x1 - 1 if outline else x1,
|
@@ -5618,66 +5859,59 @@ class MainTable(tk.Canvas):
|
|
5618
5859
|
if showing:
|
5619
5860
|
self.itemconfig(iid, fill=fill, outline=outline)
|
5620
5861
|
else:
|
5621
|
-
self.itemconfig(iid, fill=fill, outline=outline,
|
5862
|
+
self.itemconfig(iid, fill=fill, outline=outline, state="normal")
|
5622
5863
|
else:
|
5623
|
-
iid = self.create_rectangle(coords, fill=fill, outline=outline,
|
5864
|
+
iid = self.create_rectangle(coords, fill=fill, outline=outline, tags="h")
|
5624
5865
|
self.disp_high[iid] = True
|
5625
5866
|
return True
|
5626
5867
|
|
5627
|
-
def redraw_gridline(
|
5628
|
-
|
5629
|
-
|
5630
|
-
|
5631
|
-
|
5632
|
-
|
5633
|
-
|
5634
|
-
|
5635
|
-
|
5636
|
-
|
5637
|
-
|
5638
|
-
|
5639
|
-
|
5640
|
-
|
5641
|
-
|
5642
|
-
|
5643
|
-
|
5644
|
-
|
5868
|
+
def redraw_gridline(self, points: list[float]) -> None:
|
5869
|
+
if points:
|
5870
|
+
if self.hidd_grid:
|
5871
|
+
iid, sh = self.hidd_grid.popitem()
|
5872
|
+
self.coords(iid, points)
|
5873
|
+
if sh:
|
5874
|
+
self.itemconfig(
|
5875
|
+
iid,
|
5876
|
+
fill=self.PAR.ops.table_grid_fg,
|
5877
|
+
width=1,
|
5878
|
+
capstyle=tk.BUTT,
|
5879
|
+
joinstyle=tk.ROUND,
|
5880
|
+
)
|
5881
|
+
else:
|
5882
|
+
self.itemconfig(
|
5883
|
+
iid,
|
5884
|
+
fill=self.PAR.ops.table_grid_fg,
|
5885
|
+
width=1,
|
5886
|
+
capstyle=tk.BUTT,
|
5887
|
+
joinstyle=tk.ROUND,
|
5888
|
+
state="normal",
|
5889
|
+
)
|
5645
5890
|
else:
|
5646
|
-
self.
|
5647
|
-
|
5648
|
-
fill=
|
5649
|
-
width=
|
5891
|
+
iid = self.create_line(
|
5892
|
+
points,
|
5893
|
+
fill=self.PAR.ops.table_grid_fg,
|
5894
|
+
width=1,
|
5650
5895
|
capstyle=tk.BUTT,
|
5651
5896
|
joinstyle=tk.ROUND,
|
5652
|
-
|
5897
|
+
tag="g",
|
5653
5898
|
)
|
5654
|
-
|
5655
|
-
iid = self.create_line(
|
5656
|
-
points,
|
5657
|
-
fill=fill,
|
5658
|
-
width=width,
|
5659
|
-
capstyle=tk.BUTT,
|
5660
|
-
joinstyle=tk.ROUND,
|
5661
|
-
tag=tag,
|
5662
|
-
)
|
5663
|
-
self.disp_grid[iid] = True
|
5664
|
-
return iid
|
5899
|
+
self.disp_grid[iid] = True
|
5665
5900
|
|
5666
5901
|
def redraw_dropdown(
|
5667
5902
|
self,
|
5668
|
-
x1,
|
5669
|
-
y1,
|
5670
|
-
x2,
|
5671
|
-
y2,
|
5672
|
-
fill,
|
5673
|
-
outline,
|
5674
|
-
|
5675
|
-
|
5676
|
-
|
5677
|
-
|
5678
|
-
):
|
5903
|
+
x1: int | float,
|
5904
|
+
y1: int | float,
|
5905
|
+
x2: int | float,
|
5906
|
+
y2: int | float,
|
5907
|
+
fill: str,
|
5908
|
+
outline: str,
|
5909
|
+
draw_outline: bool = True,
|
5910
|
+
draw_arrow: bool = True,
|
5911
|
+
open_: bool = False,
|
5912
|
+
) -> None:
|
5679
5913
|
if draw_outline and self.PAR.ops.show_dropdown_borders:
|
5680
|
-
self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.PAR.ops.table_fg
|
5914
|
+
self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.PAR.ops.table_fg)
|
5681
5915
|
if draw_arrow:
|
5682
5916
|
mod = (self.table_txt_height - 1) if self.table_txt_height % 2 else self.table_txt_height
|
5683
5917
|
small_mod = int(mod / 5)
|
@@ -5708,13 +5942,12 @@ class MainTable(tk.Canvas):
|
|
5708
5942
|
if sh:
|
5709
5943
|
self.itemconfig(t, fill=fill)
|
5710
5944
|
else:
|
5711
|
-
self.itemconfig(t, fill=fill,
|
5945
|
+
self.itemconfig(t, fill=fill, state="normal")
|
5712
5946
|
self.lift(t)
|
5713
5947
|
else:
|
5714
5948
|
t = self.create_line(
|
5715
5949
|
points,
|
5716
5950
|
fill=fill,
|
5717
|
-
tag=tag,
|
5718
5951
|
width=2,
|
5719
5952
|
capstyle=tk.ROUND,
|
5720
5953
|
joinstyle=tk.BEVEL,
|
@@ -5729,7 +5962,6 @@ class MainTable(tk.Canvas):
|
|
5729
5962
|
y2: int | float,
|
5730
5963
|
fill: str,
|
5731
5964
|
outline: str,
|
5732
|
-
tag: str | tuple,
|
5733
5965
|
draw_check: bool = False,
|
5734
5966
|
) -> None:
|
5735
5967
|
points = rounded_box_coords(x1, y1, x2, y2)
|
@@ -5739,10 +5971,10 @@ class MainTable(tk.Canvas):
|
|
5739
5971
|
if sh:
|
5740
5972
|
self.itemconfig(t, fill=outline, outline=fill)
|
5741
5973
|
else:
|
5742
|
-
self.itemconfig(t, fill=outline, outline=fill,
|
5974
|
+
self.itemconfig(t, fill=outline, outline=fill, state="normal")
|
5743
5975
|
self.lift(t)
|
5744
5976
|
else:
|
5745
|
-
t = self.create_polygon(points, fill=outline, outline=fill,
|
5977
|
+
t = self.create_polygon(points, fill=outline, outline=fill, smooth=True)
|
5746
5978
|
self.disp_checkbox[t] = True
|
5747
5979
|
if draw_check:
|
5748
5980
|
x1 = x1 + 4
|
@@ -5756,28 +5988,13 @@ class MainTable(tk.Canvas):
|
|
5756
5988
|
if sh:
|
5757
5989
|
self.itemconfig(t, fill=fill, outline=outline)
|
5758
5990
|
else:
|
5759
|
-
self.itemconfig(t, fill=fill, outline=outline,
|
5991
|
+
self.itemconfig(t, fill=fill, outline=outline, state="normal")
|
5760
5992
|
self.lift(t)
|
5761
5993
|
else:
|
5762
|
-
t = self.create_polygon(points, fill=fill, outline=outline,
|
5994
|
+
t = self.create_polygon(points, fill=fill, outline=outline, smooth=True)
|
5763
5995
|
self.disp_checkbox[t] = True
|
5764
5996
|
|
5765
|
-
def
|
5766
|
-
self,
|
5767
|
-
redraw_header: bool = False,
|
5768
|
-
redraw_row_index: bool = False,
|
5769
|
-
redraw_table: bool = True,
|
5770
|
-
setting_views: bool = False,
|
5771
|
-
) -> bool:
|
5772
|
-
try:
|
5773
|
-
can_width = self.winfo_width()
|
5774
|
-
can_height = self.winfo_height()
|
5775
|
-
except Exception:
|
5776
|
-
return False
|
5777
|
-
row_pos_exists = self.row_positions != [0] and self.row_positions
|
5778
|
-
col_pos_exists = self.col_positions != [0] and self.col_positions
|
5779
|
-
resized_cols = False
|
5780
|
-
resized_rows = False
|
5997
|
+
def _auto_resize_columns(self, can_width: float, col_pos_exists: bool) -> bool:
|
5781
5998
|
if self.PAR.ops.auto_resize_columns and self.allow_auto_resize_columns and col_pos_exists:
|
5782
5999
|
max_w = can_width - self.PAR.ops.empty_horizontal
|
5783
6000
|
if self.PAR.ops.auto_resize_columns < self.PAR.ops.min_column_width:
|
@@ -5785,7 +6002,6 @@ class MainTable(tk.Canvas):
|
|
5785
6002
|
else:
|
5786
6003
|
min_column_width = self.PAR.ops.auto_resize_columns
|
5787
6004
|
if (len(self.col_positions) - 1) * min_column_width < max_w:
|
5788
|
-
resized_cols = True
|
5789
6005
|
change = int((max_w - self.col_positions[-1]) / (len(self.col_positions) - 1))
|
5790
6006
|
widths = [
|
5791
6007
|
int(b - a) + change - 1
|
@@ -5802,6 +6018,10 @@ class MainTable(tk.Canvas):
|
|
5802
6018
|
if i not in diffs:
|
5803
6019
|
widths[i] -= change
|
5804
6020
|
self.col_positions = list(accumulate(chain([0], widths)))
|
6021
|
+
return True
|
6022
|
+
return False
|
6023
|
+
|
6024
|
+
def _auto_resize_rows(self, can_height: float, row_pos_exists: bool) -> bool:
|
5805
6025
|
if self.PAR.ops.auto_resize_rows and self.allow_auto_resize_rows and row_pos_exists:
|
5806
6026
|
max_h = can_height - self.PAR.ops.empty_vertical
|
5807
6027
|
if self.PAR.ops.auto_resize_rows < self.min_row_height:
|
@@ -5809,7 +6029,6 @@ class MainTable(tk.Canvas):
|
|
5809
6029
|
else:
|
5810
6030
|
min_row_height = self.PAR.ops.auto_resize_rows
|
5811
6031
|
if (len(self.row_positions) - 1) * min_row_height < max_h:
|
5812
|
-
resized_rows = True
|
5813
6032
|
change = int((max_h - self.row_positions[-1]) / (len(self.row_positions) - 1))
|
5814
6033
|
heights = [
|
5815
6034
|
int(b - a) + change - 1
|
@@ -5826,6 +6045,10 @@ class MainTable(tk.Canvas):
|
|
5826
6045
|
if i not in diffs:
|
5827
6046
|
heights[i] -= change
|
5828
6047
|
self.row_positions = list(accumulate(chain([0], heights)))
|
6048
|
+
return True
|
6049
|
+
return False
|
6050
|
+
|
6051
|
+
def _manage_scroll_bars(self, can_height: float, can_width: float) -> None:
|
5829
6052
|
if (
|
5830
6053
|
self.PAR.ops.auto_resize_row_index is not True
|
5831
6054
|
and can_width >= self.col_positions[-1] + self.PAR.ops.empty_horizontal
|
@@ -5852,6 +6075,81 @@ class MainTable(tk.Canvas):
|
|
5852
6075
|
):
|
5853
6076
|
self.PAR.yscroll.grid(row=0, column=2, rowspan=3, sticky="nswe")
|
5854
6077
|
self.PAR.yscroll_showing = True
|
6078
|
+
|
6079
|
+
def _overflow(
|
6080
|
+
self,
|
6081
|
+
cells: dict,
|
6082
|
+
rnge: Generator[int],
|
6083
|
+
datarn: int,
|
6084
|
+
) -> Generator[float]:
|
6085
|
+
for c_ in rnge:
|
6086
|
+
if (
|
6087
|
+
cells[(datarn, cells["datacn"][c_])]
|
6088
|
+
or (datarn, cells["datacn"][c_]) in cells["dropdown"]
|
6089
|
+
or (datarn, cells["datacn"][c_]) in cells["checkbox"]
|
6090
|
+
):
|
6091
|
+
return
|
6092
|
+
else:
|
6093
|
+
yield self.col_positions[c_ + 1] - self.col_positions[c_]
|
6094
|
+
|
6095
|
+
def _redraw_precache_cells(
|
6096
|
+
self,
|
6097
|
+
text_start_row: int,
|
6098
|
+
text_end_row: int,
|
6099
|
+
text_start_col: int,
|
6100
|
+
text_end_col: int,
|
6101
|
+
) -> dict:
|
6102
|
+
cells = {"datarn": {}, "datacn": {}, "dropdown": {}, "checkbox": {}}
|
6103
|
+
for r in range(text_start_row, text_end_row):
|
6104
|
+
datarn = r if self.all_rows_displayed else self.displayed_rows[r]
|
6105
|
+
cells["datarn"][r] = datarn
|
6106
|
+
for c in range(text_start_col, text_end_col):
|
6107
|
+
if c in cells["datacn"]:
|
6108
|
+
datacn = cells["datacn"][c]
|
6109
|
+
else:
|
6110
|
+
datacn = c if self.all_columns_displayed else self.displayed_columns[c]
|
6111
|
+
cells["datacn"][c] = datacn
|
6112
|
+
if kwargs := self.get_cell_kwargs(datarn, datacn, key="dropdown"):
|
6113
|
+
cells["dropdown"][(datarn, datacn)] = kwargs
|
6114
|
+
elif kwargs := self.get_cell_kwargs(datarn, datacn, key="checkbox"):
|
6115
|
+
cells["checkbox"][(datarn, datacn)] = kwargs
|
6116
|
+
cells[(datarn, datacn)] = self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
|
6117
|
+
return cells
|
6118
|
+
|
6119
|
+
def wrap_get_char_w(self, c: str) -> int:
|
6120
|
+
self.txt_measure_canvas.itemconfig(
|
6121
|
+
self.txt_measure_canvas_text,
|
6122
|
+
text=_test_str + c,
|
6123
|
+
font=self.table_font,
|
6124
|
+
)
|
6125
|
+
b = self.txt_measure_canvas.bbox(self.txt_measure_canvas_text)
|
6126
|
+
if c in self.char_widths[self.table_font]:
|
6127
|
+
return self.char_widths[self.table_font][c]
|
6128
|
+
else:
|
6129
|
+
wd = b[2] - b[0] - self.table_test_str_w
|
6130
|
+
self.char_widths[self.table_font][c] = wd
|
6131
|
+
return wd
|
6132
|
+
|
6133
|
+
def main_table_redraw_grid_and_text(
|
6134
|
+
self,
|
6135
|
+
redraw_header: bool = False,
|
6136
|
+
redraw_row_index: bool = False,
|
6137
|
+
redraw_table: bool = True,
|
6138
|
+
setting_views: bool = False,
|
6139
|
+
set_scrollregion: bool = True,
|
6140
|
+
) -> bool:
|
6141
|
+
try:
|
6142
|
+
can_width = self.winfo_width()
|
6143
|
+
can_height = self.winfo_height()
|
6144
|
+
except Exception:
|
6145
|
+
return False
|
6146
|
+
row_pos_exists = self.row_positions != [0] and self.row_positions
|
6147
|
+
col_pos_exists = self.col_positions != [0] and self.col_positions
|
6148
|
+
|
6149
|
+
resized_cols = self._auto_resize_columns(can_width=can_width, col_pos_exists=col_pos_exists)
|
6150
|
+
resized_rows = self._auto_resize_rows(can_height=can_height, row_pos_exists=row_pos_exists)
|
6151
|
+
self._manage_scroll_bars(can_height=can_height, can_width=can_width)
|
6152
|
+
|
5855
6153
|
last_col_line_pos = self.col_positions[-1] + 1
|
5856
6154
|
last_row_line_pos = self.row_positions[-1] + 1
|
5857
6155
|
scrollregion = (
|
@@ -5860,28 +6158,33 @@ class MainTable(tk.Canvas):
|
|
5860
6158
|
last_col_line_pos + self.PAR.ops.empty_horizontal + 2,
|
5861
6159
|
last_row_line_pos + self.PAR.ops.empty_vertical + 2,
|
5862
6160
|
)
|
5863
|
-
if setting_views or scrollregion != self.scrollregion:
|
5864
|
-
|
6161
|
+
if set_scrollregion and (setting_views or scrollregion != self.scrollregion):
|
6162
|
+
try:
|
6163
|
+
self.configure(scrollregion=scrollregion)
|
6164
|
+
except Exception:
|
6165
|
+
return False
|
5865
6166
|
self.scrollregion = scrollregion
|
5866
|
-
|
5867
|
-
|
5868
|
-
|
6167
|
+
if (
|
6168
|
+
not self.CH.configure_scrollregion(last_col_line_pos)
|
6169
|
+
or not self.RI.configure_scrollregion(last_row_line_pos)
|
6170
|
+
or setting_views
|
6171
|
+
):
|
5869
6172
|
return False
|
6173
|
+
|
5870
6174
|
scrollpos_top = self.canvasy(0)
|
5871
6175
|
scrollpos_bot = self.canvasy(can_height)
|
5872
6176
|
scrollpos_left = self.canvasx(0)
|
5873
6177
|
scrollpos_right = self.canvasx(can_width)
|
5874
|
-
|
5875
6178
|
grid_start_row = bisect_left(self.row_positions, scrollpos_top)
|
5876
6179
|
grid_end_row = bisect_right(self.row_positions, scrollpos_bot)
|
5877
6180
|
grid_start_col = bisect_left(self.col_positions, scrollpos_left)
|
5878
6181
|
grid_end_col = bisect_right(self.col_positions, scrollpos_right)
|
5879
|
-
|
5880
6182
|
text_start_row = grid_start_row - 1 if grid_start_row else grid_start_row
|
5881
6183
|
text_end_row = grid_end_row - 1 if grid_end_row == len(self.row_positions) else grid_end_row
|
5882
6184
|
text_start_col = grid_start_col - 1 if grid_start_col else grid_start_col
|
5883
6185
|
text_end_col = grid_end_col - 1 if grid_end_col == len(self.col_positions) else grid_end_col
|
5884
6186
|
|
6187
|
+
# check if auto resizing row index
|
5885
6188
|
changed_w = False
|
5886
6189
|
if self.PAR.ops.auto_resize_row_index and redraw_row_index and self.show_index:
|
5887
6190
|
changed_w = self.RI.auto_set_index_width(
|
@@ -5894,6 +6197,10 @@ class MainTable(tk.Canvas):
|
|
5894
6197
|
for widget in (self, self.RI, self.CH, self.TL):
|
5895
6198
|
widget.update_idletasks()
|
5896
6199
|
return False
|
6200
|
+
# important vars
|
6201
|
+
x_stop = min(last_col_line_pos, scrollpos_right)
|
6202
|
+
y_stop = min(last_row_line_pos, scrollpos_bot)
|
6203
|
+
# manage find window
|
5897
6204
|
if self.find_window.open:
|
5898
6205
|
w, h, x, y = self.get_find_window_dimensions_coords(w_width=self.winfo_width())
|
5899
6206
|
self.coords(self.find_window.canvas_id, x, y)
|
@@ -5903,89 +6210,73 @@ class MainTable(tk.Canvas):
|
|
5903
6210
|
height=h,
|
5904
6211
|
state="normal",
|
5905
6212
|
)
|
5906
|
-
|
5907
|
-
|
5908
|
-
|
5909
|
-
|
5910
|
-
|
5911
|
-
|
5912
|
-
|
5913
|
-
|
5914
|
-
|
5915
|
-
|
5916
|
-
|
5917
|
-
|
5918
|
-
|
5919
|
-
|
5920
|
-
|
5921
|
-
|
5922
|
-
|
5923
|
-
y_stop = last_row_line_pos
|
5924
|
-
if redraw_table and self.PAR.ops.show_horizontal_grid and row_pos_exists:
|
5925
|
-
if self.PAR.ops.horizontal_grid_to_end_of_window:
|
5926
|
-
x_grid_stop = scrollpos_right + can_width
|
5927
|
-
else:
|
5928
|
-
if last_col_line_pos > scrollpos_right:
|
5929
|
-
x_grid_stop = x_stop + 1
|
6213
|
+
# redraw table
|
6214
|
+
if redraw_table:
|
6215
|
+
# reset canvas item storage
|
6216
|
+
self.hidd_text.update(self.disp_text)
|
6217
|
+
self.disp_text = {}
|
6218
|
+
self.hidd_high.update(self.disp_high)
|
6219
|
+
self.disp_high = {}
|
6220
|
+
self.hidd_grid.update(self.disp_grid)
|
6221
|
+
self.disp_grid = {}
|
6222
|
+
self.hidd_dropdown.update(self.disp_dropdown)
|
6223
|
+
self.disp_dropdown = {}
|
6224
|
+
self.hidd_checkbox.update(self.disp_checkbox)
|
6225
|
+
self.disp_checkbox = {}
|
6226
|
+
# manage horizontal grid lines
|
6227
|
+
if self.PAR.ops.show_horizontal_grid and row_pos_exists:
|
6228
|
+
if self.PAR.ops.horizontal_grid_to_end_of_window:
|
6229
|
+
x_grid_stop = scrollpos_right + can_width
|
5930
6230
|
else:
|
5931
|
-
|
5932
|
-
|
5933
|
-
|
5934
|
-
|
5935
|
-
(
|
5936
|
-
scrollpos_left - 1,
|
5937
|
-
self.row_positions[r],
|
5938
|
-
x_grid_stop,
|
5939
|
-
self.row_positions[r],
|
5940
|
-
scrollpos_left - 1,
|
5941
|
-
self.row_positions[r],
|
5942
|
-
scrollpos_left - 1,
|
5943
|
-
self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
|
5944
|
-
)
|
5945
|
-
for r in range(grid_start_row, grid_end_row)
|
5946
|
-
]
|
5947
|
-
)
|
5948
|
-
)
|
5949
|
-
if points:
|
6231
|
+
if last_col_line_pos > scrollpos_right:
|
6232
|
+
x_grid_stop = x_stop + 1
|
6233
|
+
else:
|
6234
|
+
x_grid_stop = x_stop - 1
|
5950
6235
|
self.redraw_gridline(
|
5951
|
-
points=
|
5952
|
-
|
5953
|
-
|
5954
|
-
|
5955
|
-
|
5956
|
-
|
5957
|
-
|
5958
|
-
|
5959
|
-
|
5960
|
-
|
5961
|
-
|
5962
|
-
|
5963
|
-
|
5964
|
-
points = list(
|
5965
|
-
chain.from_iterable(
|
5966
|
-
[
|
5967
|
-
(
|
5968
|
-
self.col_positions[c],
|
5969
|
-
scrollpos_top - 1,
|
5970
|
-
self.col_positions[c],
|
5971
|
-
y_grid_stop,
|
5972
|
-
self.col_positions[c],
|
5973
|
-
scrollpos_top - 1,
|
5974
|
-
self.col_positions[c + 1] if len(self.col_positions) - 1 > c else self.col_positions[c],
|
5975
|
-
scrollpos_top - 1,
|
6236
|
+
points=tuple(
|
6237
|
+
chain.from_iterable(
|
6238
|
+
(
|
6239
|
+
scrollpos_left - 1,
|
6240
|
+
self.row_positions[r],
|
6241
|
+
x_grid_stop,
|
6242
|
+
self.row_positions[r],
|
6243
|
+
scrollpos_left - 1,
|
6244
|
+
self.row_positions[r],
|
6245
|
+
scrollpos_left - 1,
|
6246
|
+
self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
|
6247
|
+
)
|
6248
|
+
for r in range(grid_start_row, grid_end_row)
|
5976
6249
|
)
|
5977
|
-
|
5978
|
-
]
|
6250
|
+
)
|
5979
6251
|
)
|
5980
|
-
|
5981
|
-
if
|
6252
|
+
# manage vertical grid lines
|
6253
|
+
if self.PAR.ops.show_vertical_grid and col_pos_exists:
|
6254
|
+
if self.PAR.ops.vertical_grid_to_end_of_window:
|
6255
|
+
y_grid_stop = scrollpos_bot + can_height
|
6256
|
+
else:
|
6257
|
+
if last_row_line_pos > scrollpos_bot:
|
6258
|
+
y_grid_stop = y_stop + 1
|
6259
|
+
else:
|
6260
|
+
y_grid_stop = y_stop - 1
|
5982
6261
|
self.redraw_gridline(
|
5983
|
-
points=
|
5984
|
-
|
5985
|
-
|
5986
|
-
|
6262
|
+
points=tuple(
|
6263
|
+
chain.from_iterable(
|
6264
|
+
(
|
6265
|
+
self.col_positions[c],
|
6266
|
+
scrollpos_top - 1,
|
6267
|
+
self.col_positions[c],
|
6268
|
+
y_grid_stop,
|
6269
|
+
self.col_positions[c],
|
6270
|
+
scrollpos_top - 1,
|
6271
|
+
self.col_positions[c + 1] if len(self.col_positions) - 1 > c else self.col_positions[c],
|
6272
|
+
scrollpos_top - 1,
|
6273
|
+
)
|
6274
|
+
for c in range(grid_start_col, grid_end_col)
|
6275
|
+
)
|
6276
|
+
),
|
5987
6277
|
)
|
5988
|
-
|
6278
|
+
font = self.PAR.ops.table_font
|
6279
|
+
dd_coords = self.dropdown.get_coords()
|
5989
6280
|
selections = self.get_redraw_selections(text_start_row, grid_end_row, text_start_col, grid_end_col)
|
5990
6281
|
sel_cells_bg = color_tup(self.PAR.ops.table_selected_cells_bg)
|
5991
6282
|
sel_cols_bg = color_tup(self.PAR.ops.table_selected_columns_bg)
|
@@ -6007,7 +6298,6 @@ class MainTable(tk.Canvas):
|
|
6007
6298
|
else:
|
6008
6299
|
alternate_color = None
|
6009
6300
|
dont_blend = tuple()
|
6010
|
-
|
6011
6301
|
if not self.PAR.ops.show_selected_cells_border:
|
6012
6302
|
override = (
|
6013
6303
|
color_tup(self.PAR.ops.table_selected_cells_fg),
|
@@ -6016,22 +6306,23 @@ class MainTable(tk.Canvas):
|
|
6016
6306
|
)
|
6017
6307
|
else:
|
6018
6308
|
override = tuple()
|
6309
|
+
allow_overflow = self.PAR.ops.allow_cell_overflow
|
6310
|
+
wrap = self.PAR.ops.table_wrap
|
6311
|
+
cells = self._redraw_precache_cells(
|
6312
|
+
text_start_row=text_start_row,
|
6313
|
+
text_end_row=text_end_row,
|
6314
|
+
text_start_col=text_start_col,
|
6315
|
+
text_end_col=text_end_col,
|
6316
|
+
)
|
6317
|
+
for r in range(text_start_row, text_end_row):
|
6318
|
+
rtopgridln = self.row_positions[r]
|
6319
|
+
rbotgridln = self.row_positions[r + 1]
|
6320
|
+
datarn = cells["datarn"][r]
|
6019
6321
|
|
6020
|
-
|
6021
|
-
font = self.PAR.ops.table_font
|
6022
|
-
dd_coords = self.dropdown.get_coords()
|
6023
|
-
for c in range(text_start_col, text_end_col):
|
6024
|
-
for r in rows_:
|
6025
|
-
rtopgridln = self.row_positions[r]
|
6026
|
-
rbotgridln = self.row_positions[r + 1]
|
6027
|
-
if rbotgridln - rtopgridln < self.table_txt_height:
|
6028
|
-
continue
|
6322
|
+
for c in range(text_start_col, text_end_col):
|
6029
6323
|
cleftgridln = self.col_positions[c]
|
6030
6324
|
crightgridln = self.col_positions[c + 1]
|
6031
|
-
|
6032
|
-
datarn = self.datarn(r)
|
6033
|
-
datacn = self.datacn(c)
|
6034
|
-
|
6325
|
+
datacn = cells["datacn"][c]
|
6035
6326
|
fill, dd_drawn = self.redraw_highlight_get_text_fg(
|
6036
6327
|
r=r,
|
6037
6328
|
c=c,
|
@@ -6049,79 +6340,48 @@ class MainTable(tk.Canvas):
|
|
6049
6340
|
dont_blend=(r, c) == dont_blend,
|
6050
6341
|
alternate_color=alternate_color,
|
6051
6342
|
)
|
6052
|
-
align
|
6053
|
-
if align:
|
6054
|
-
align = align
|
6055
|
-
else:
|
6343
|
+
if not (align := self.get_cell_kwargs(datarn, datacn, key="align")):
|
6056
6344
|
align = self.align
|
6057
|
-
|
6058
|
-
if
|
6059
|
-
|
6060
|
-
if
|
6061
|
-
|
6062
|
-
|
6063
|
-
cleftgridln,
|
6064
|
-
rtopgridln,
|
6065
|
-
crightgridln,
|
6066
|
-
self.row_positions[r + 1],
|
6067
|
-
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
|
6068
|
-
outline=fill,
|
6069
|
-
tag=f"dd_{r}_{c}",
|
6070
|
-
draw_outline=not dd_drawn,
|
6071
|
-
draw_arrow=mw >= 5,
|
6072
|
-
open_=dd_coords == (r, c),
|
6073
|
-
)
|
6074
|
-
else:
|
6075
|
-
mw = crightgridln - cleftgridln - 1
|
6076
|
-
elif align == "e":
|
6077
|
-
if kwargs:
|
6078
|
-
mw = crightgridln - cleftgridln - self.table_txt_height - 2
|
6345
|
+
|
6346
|
+
if kwargs := cells["dropdown"].get((datarn, datacn), None):
|
6347
|
+
max_width = crightgridln - cleftgridln - self.table_txt_height - 5
|
6348
|
+
if align.endswith("w"):
|
6349
|
+
draw_x = cleftgridln + 2
|
6350
|
+
elif align.endswith("e"):
|
6079
6351
|
draw_x = crightgridln - 5 - self.table_txt_height
|
6080
|
-
|
6081
|
-
cleftgridln,
|
6082
|
-
rtopgridln,
|
6083
|
-
crightgridln,
|
6084
|
-
self.row_positions[r + 1],
|
6085
|
-
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
|
6086
|
-
outline=fill,
|
6087
|
-
tag=f"dd_{r}_{c}",
|
6088
|
-
draw_outline=not dd_drawn,
|
6089
|
-
draw_arrow=mw >= 5,
|
6090
|
-
open_=dd_coords == (r, c),
|
6091
|
-
)
|
6092
|
-
else:
|
6093
|
-
mw = crightgridln - cleftgridln - 1
|
6094
|
-
draw_x = crightgridln - 3
|
6095
|
-
elif align == "center":
|
6096
|
-
if kwargs:
|
6097
|
-
mw = crightgridln - cleftgridln - self.table_txt_height - 2
|
6352
|
+
elif align.endswith("n"):
|
6098
6353
|
draw_x = cleftgridln + ceil((crightgridln - cleftgridln - self.table_txt_height) / 2)
|
6099
|
-
|
6100
|
-
|
6101
|
-
|
6102
|
-
|
6103
|
-
|
6104
|
-
|
6105
|
-
|
6106
|
-
|
6107
|
-
|
6108
|
-
|
6109
|
-
|
6110
|
-
|
6111
|
-
|
6112
|
-
|
6354
|
+
self.redraw_dropdown(
|
6355
|
+
cleftgridln,
|
6356
|
+
rtopgridln,
|
6357
|
+
crightgridln,
|
6358
|
+
self.row_positions[r + 1],
|
6359
|
+
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
|
6360
|
+
outline=fill,
|
6361
|
+
draw_outline=not dd_drawn,
|
6362
|
+
draw_arrow=max_width >= 5,
|
6363
|
+
open_=dd_coords == (r, c),
|
6364
|
+
)
|
6365
|
+
else:
|
6366
|
+
max_width = crightgridln - cleftgridln - 2
|
6367
|
+
if align.endswith("w"):
|
6368
|
+
draw_x = cleftgridln + 2
|
6369
|
+
elif align.endswith("e"):
|
6370
|
+
draw_x = crightgridln - 2
|
6371
|
+
elif align.endswith("n"):
|
6113
6372
|
draw_x = cleftgridln + floor((crightgridln - cleftgridln) / 2)
|
6114
|
-
|
6115
|
-
|
6116
|
-
|
6373
|
+
|
6374
|
+
if (
|
6375
|
+
kwargs := cells["checkbox"].get((datarn, datacn), None)
|
6376
|
+
) and max_width > self.table_txt_height + 1:
|
6117
6377
|
box_w = self.table_txt_height + 1
|
6118
|
-
if align
|
6378
|
+
if align.endswith("w"):
|
6119
6379
|
draw_x += box_w + 3
|
6120
|
-
elif align
|
6380
|
+
elif align.endswith("n"):
|
6121
6381
|
draw_x += ceil(box_w / 2) + 1
|
6122
|
-
|
6382
|
+
max_width -= box_w + 4
|
6123
6383
|
try:
|
6124
|
-
draw_check = self.data[datarn][datacn]
|
6384
|
+
draw_check = bool(self.data[datarn][datacn])
|
6125
6385
|
except Exception:
|
6126
6386
|
draw_check = False
|
6127
6387
|
self.redraw_checkbox(
|
@@ -6131,92 +6391,105 @@ class MainTable(tk.Canvas):
|
|
6131
6391
|
rtopgridln + self.table_txt_height + 3,
|
6132
6392
|
fill=fill if kwargs["state"] == "normal" else self.PAR.ops.table_grid_fg,
|
6133
6393
|
outline="",
|
6134
|
-
tag="cb",
|
6135
6394
|
draw_check=draw_check,
|
6136
6395
|
)
|
6137
|
-
|
6396
|
+
text = cells[(datarn, datacn)]
|
6138
6397
|
if (
|
6139
|
-
|
6140
|
-
and
|
6141
|
-
and
|
6142
|
-
|
6143
|
-
or (align == "e" and cleftgridln + 5 > scrollpos_right)
|
6144
|
-
or (align == "center" and cleftgridln + 5 > scrollpos_right)
|
6145
|
-
)
|
6398
|
+
not text
|
6399
|
+
or (align.endswith("w") and draw_x > scrollpos_right)
|
6400
|
+
or (align.endswith("e") and cleftgridln + 5 > scrollpos_right)
|
6401
|
+
or (align.endswith("n") and cleftgridln + 5 > scrollpos_right)
|
6146
6402
|
):
|
6147
|
-
|
6148
|
-
|
6149
|
-
if
|
6150
|
-
|
6151
|
-
|
6152
|
-
|
6153
|
-
|
6154
|
-
|
6155
|
-
|
6156
|
-
|
6157
|
-
|
6158
|
-
|
6159
|
-
|
6160
|
-
|
6161
|
-
|
6162
|
-
|
6163
|
-
|
6164
|
-
|
6165
|
-
|
6166
|
-
|
6167
|
-
|
6168
|
-
|
6169
|
-
|
6170
|
-
|
6171
|
-
|
6172
|
-
|
6173
|
-
|
6174
|
-
|
6403
|
+
continue
|
6404
|
+
if allow_overflow and not kwargs:
|
6405
|
+
if align.endswith("w"):
|
6406
|
+
max_width += sum(self._overflow(cells, range(c + 1, text_end_col), datarn))
|
6407
|
+
elif align.endswith("e"):
|
6408
|
+
max_width += sum(self._overflow(cells, reversed(range(text_start_col, c)), datarn))
|
6409
|
+
elif align.endswith("n"):
|
6410
|
+
...
|
6411
|
+
if max_width <= 1:
|
6412
|
+
continue
|
6413
|
+
start_line = max(0, int((scrollpos_top - rtopgridln) / self.table_txt_height))
|
6414
|
+
draw_y = rtopgridln + 3 + (start_line * self.table_txt_height)
|
6415
|
+
gen_lines = wrap_text(
|
6416
|
+
text=text,
|
6417
|
+
max_width=max_width,
|
6418
|
+
max_lines=int((rbotgridln - rtopgridln - 2) / self.table_txt_height),
|
6419
|
+
char_width_fn=self.wrap_get_char_w,
|
6420
|
+
widths=self.char_widths[font],
|
6421
|
+
wrap=wrap,
|
6422
|
+
start_line=start_line,
|
6423
|
+
)
|
6424
|
+
if align.endswith(("w", "e")):
|
6425
|
+
if self.hidd_text:
|
6426
|
+
iid, showing = self.hidd_text.popitem()
|
6427
|
+
self.coords(iid, draw_x, draw_y)
|
6428
|
+
if showing:
|
6429
|
+
self.itemconfig(
|
6430
|
+
iid,
|
6431
|
+
text="\n".join(gen_lines),
|
6432
|
+
fill=fill,
|
6433
|
+
font=font,
|
6434
|
+
anchor=align,
|
6435
|
+
)
|
6436
|
+
else:
|
6437
|
+
self.itemconfig(
|
6438
|
+
iid,
|
6439
|
+
text="\n".join(gen_lines),
|
6440
|
+
fill=fill,
|
6441
|
+
font=font,
|
6442
|
+
anchor=align,
|
6443
|
+
state="normal",
|
6444
|
+
)
|
6445
|
+
self.tag_raise(iid)
|
6446
|
+
else:
|
6447
|
+
iid = self.create_text(
|
6448
|
+
draw_x,
|
6449
|
+
draw_y,
|
6450
|
+
text="\n".join(gen_lines),
|
6451
|
+
fill=fill,
|
6452
|
+
font=font,
|
6453
|
+
anchor=align,
|
6454
|
+
tags="t",
|
6455
|
+
)
|
6456
|
+
self.disp_text[iid] = True
|
6457
|
+
|
6458
|
+
elif align.endswith("n"):
|
6459
|
+
for text in gen_lines:
|
6460
|
+
if self.hidd_text:
|
6461
|
+
iid, showing = self.hidd_text.popitem()
|
6462
|
+
self.coords(iid, draw_x, draw_y)
|
6463
|
+
if showing:
|
6464
|
+
self.itemconfig(
|
6465
|
+
iid,
|
6466
|
+
text=text,
|
6467
|
+
fill=fill,
|
6468
|
+
font=font,
|
6469
|
+
anchor=align,
|
6470
|
+
)
|
6175
6471
|
else:
|
6176
|
-
|
6177
|
-
|
6178
|
-
|
6179
|
-
text=txt,
|
6472
|
+
self.itemconfig(
|
6473
|
+
iid,
|
6474
|
+
text=text,
|
6180
6475
|
fill=fill,
|
6181
6476
|
font=font,
|
6182
6477
|
anchor=align,
|
6183
|
-
|
6478
|
+
state="normal",
|
6184
6479
|
)
|
6185
|
-
self.
|
6186
|
-
|
6187
|
-
|
6188
|
-
|
6189
|
-
|
6190
|
-
|
6191
|
-
|
6192
|
-
|
6193
|
-
|
6194
|
-
|
6195
|
-
|
6196
|
-
|
6197
|
-
|
6198
|
-
txt = txt[len(txt) - int(len(txt) * (mw / wd)) :]
|
6199
|
-
self.itemconfig(iid, text=txt)
|
6200
|
-
wd = self.bbox(iid)
|
6201
|
-
while wd[2] - wd[0] > mw:
|
6202
|
-
txt = txt[1:]
|
6203
|
-
self.itemconfig(iid, text=txt)
|
6204
|
-
wd = self.bbox(iid)
|
6205
|
-
elif align == "center":
|
6206
|
-
self.c_align_cyc = cycle(self.centre_alignment_text_mod_indexes)
|
6207
|
-
tmod = ceil((len(txt) - int(len(txt) * (mw / wd))) / 2)
|
6208
|
-
txt = txt[tmod - 1 : -tmod]
|
6209
|
-
self.itemconfig(iid, text=txt)
|
6210
|
-
wd = self.bbox(iid)
|
6211
|
-
while wd[2] - wd[0] > mw:
|
6212
|
-
txt = txt[next(self.c_align_cyc)]
|
6213
|
-
self.itemconfig(iid, text=txt)
|
6214
|
-
wd = self.bbox(iid)
|
6215
|
-
self.coords(iid, draw_x, draw_y)
|
6216
|
-
draw_y += self.table_xtra_lines_increment
|
6217
|
-
if draw_y + self.table_half_txt_height - 1 > rbotgridln:
|
6218
|
-
break
|
6219
|
-
if redraw_table:
|
6480
|
+
self.tag_raise(iid)
|
6481
|
+
else:
|
6482
|
+
iid = self.create_text(
|
6483
|
+
draw_x,
|
6484
|
+
draw_y,
|
6485
|
+
text=text,
|
6486
|
+
fill=fill,
|
6487
|
+
font=font,
|
6488
|
+
anchor=align,
|
6489
|
+
tags="t",
|
6490
|
+
)
|
6491
|
+
self.disp_text[iid] = True
|
6492
|
+
draw_y += self.table_txt_height
|
6220
6493
|
for dct in (
|
6221
6494
|
self.hidd_text,
|
6222
6495
|
self.hidd_high,
|
@@ -6234,6 +6507,10 @@ class MainTable(tk.Canvas):
|
|
6234
6507
|
self.tag_raise(box.bd_iid)
|
6235
6508
|
if self.selected:
|
6236
6509
|
self.tag_raise(self.selected.iid)
|
6510
|
+
if self.RI.disp_resize_lines:
|
6511
|
+
self.tag_raise("rh")
|
6512
|
+
if self.CH.disp_resize_lines:
|
6513
|
+
self.tag_raise("rw")
|
6237
6514
|
if redraw_header and self.show_header:
|
6238
6515
|
self.CH.redraw_grid_and_text(
|
6239
6516
|
last_col_line_pos=last_col_line_pos,
|
@@ -6245,6 +6522,7 @@ class MainTable(tk.Canvas):
|
|
6245
6522
|
text_end_col=text_end_col,
|
6246
6523
|
scrollpos_right=scrollpos_right,
|
6247
6524
|
col_pos_exists=col_pos_exists,
|
6525
|
+
set_scrollregion=set_scrollregion,
|
6248
6526
|
)
|
6249
6527
|
if redraw_row_index and self.show_index:
|
6250
6528
|
self.RI.redraw_grid_and_text(
|
@@ -6257,6 +6535,7 @@ class MainTable(tk.Canvas):
|
|
6257
6535
|
text_end_row=text_end_row,
|
6258
6536
|
scrollpos_bot=scrollpos_bot,
|
6259
6537
|
row_pos_exists=row_pos_exists,
|
6538
|
+
set_scrollregion=set_scrollregion,
|
6260
6539
|
)
|
6261
6540
|
event_data = {"sheetname": "", "header": redraw_header, "row_index": redraw_row_index, "table": redraw_table}
|
6262
6541
|
self.PAR.emit_event("<<SheetRedrawn>>", data=event_data)
|
@@ -6313,7 +6592,7 @@ class MainTable(tk.Canvas):
|
|
6313
6592
|
# set current to a particular existing selection box
|
6314
6593
|
if isinstance(item, int) and item in self.selection_boxes:
|
6315
6594
|
selection_box = self.selection_boxes[item]
|
6316
|
-
r1, c1,
|
6595
|
+
r1, c1, _, _ = selection_box.coords
|
6317
6596
|
if box_created(r1 if r is None else r, c1 if c is None else c, selection_box):
|
6318
6597
|
return
|
6319
6598
|
|
@@ -6732,7 +7011,7 @@ class MainTable(tk.Canvas):
|
|
6732
7011
|
|
6733
7012
|
def get_redraw_selections(self, startr: int, endr: int, startc: int, endc: int) -> dict:
|
6734
7013
|
d = defaultdict(set)
|
6735
|
-
for
|
7014
|
+
for _, box in self.get_selection_items():
|
6736
7015
|
r1, c1, r2, c2 = box.coords
|
6737
7016
|
if box.type_ == "cells":
|
6738
7017
|
for r in range(startr, endr):
|
@@ -6770,7 +7049,7 @@ class MainTable(tk.Canvas):
|
|
6770
7049
|
if get_cells:
|
6771
7050
|
s = {
|
6772
7051
|
(r, c)
|
6773
|
-
for
|
7052
|
+
for _, box in self.get_selection_items(cells=False, columns=False)
|
6774
7053
|
for r in range(box.coords.from_r, box.coords.upto_r)
|
6775
7054
|
for c in range(0, len(self.col_positions) - 1)
|
6776
7055
|
}
|
@@ -6779,7 +7058,7 @@ class MainTable(tk.Canvas):
|
|
6779
7058
|
else:
|
6780
7059
|
s = {
|
6781
7060
|
r
|
6782
|
-
for
|
7061
|
+
for _, box in self.get_selection_items(cells=False, columns=False)
|
6783
7062
|
for r in range(box.coords.from_r, box.coords.upto_r)
|
6784
7063
|
}
|
6785
7064
|
if get_cells_as_rows:
|
@@ -6794,7 +7073,7 @@ class MainTable(tk.Canvas):
|
|
6794
7073
|
if get_cells:
|
6795
7074
|
s = {
|
6796
7075
|
(r, c)
|
6797
|
-
for
|
7076
|
+
for _, box in self.get_selection_items(cells=False, rows=False)
|
6798
7077
|
for r in range(0, len(self.row_positions) - 1)
|
6799
7078
|
for c in range(box.coords.from_c, box.coords.upto_c)
|
6800
7079
|
}
|
@@ -6803,7 +7082,7 @@ class MainTable(tk.Canvas):
|
|
6803
7082
|
else:
|
6804
7083
|
s = {
|
6805
7084
|
c
|
6806
|
-
for
|
7085
|
+
for _, box in self.get_selection_items(cells=False, rows=False)
|
6807
7086
|
for c in range(box.coords.from_c, box.coords.upto_c)
|
6808
7087
|
}
|
6809
7088
|
if get_cells_as_cols:
|
@@ -6817,7 +7096,7 @@ class MainTable(tk.Canvas):
|
|
6817
7096
|
) -> set[tuple[int, int]]:
|
6818
7097
|
return {
|
6819
7098
|
(r, c)
|
6820
|
-
for
|
7099
|
+
for _, box in self.get_selection_items(rows=get_rows, columns=get_cols)
|
6821
7100
|
for r in range(box.coords.from_r, box.coords.upto_r)
|
6822
7101
|
for c in range(box.coords.from_c, box.coords.upto_c)
|
6823
7102
|
}
|
@@ -6829,16 +7108,16 @@ class MainTable(tk.Canvas):
|
|
6829
7108
|
) -> Generator[tuple[int, int]]:
|
6830
7109
|
yield from (
|
6831
7110
|
(r, c)
|
6832
|
-
for
|
7111
|
+
for _, box in self.get_selection_items(rows=get_rows, columns=get_cols)
|
6833
7112
|
for r in range(box.coords.from_r, box.coords.upto_r)
|
6834
7113
|
for c in range(box.coords.from_c, box.coords.upto_c)
|
6835
7114
|
)
|
6836
7115
|
|
6837
7116
|
def get_all_selection_boxes(self) -> tuple[tuple[int, int, int, int]]:
|
6838
|
-
return tuple(box.coords for
|
7117
|
+
return tuple(box.coords for _, box in self.get_selection_items())
|
6839
7118
|
|
6840
7119
|
def get_all_selection_boxes_with_types(self) -> list[tuple[tuple[int, int, int, int], str]]:
|
6841
|
-
return [Box_st(box.coords, box.type_) for
|
7120
|
+
return [Box_st(box.coords, box.type_) for _, box in self.get_selection_items()]
|
6842
7121
|
|
6843
7122
|
def all_selected(self) -> bool:
|
6844
7123
|
return any(
|
@@ -6858,7 +7137,7 @@ class MainTable(tk.Canvas):
|
|
6858
7137
|
and isinstance(c, int)
|
6859
7138
|
and any(
|
6860
7139
|
box.coords.from_r <= r and box.coords.upto_r > r and box.coords.from_c <= c and box.coords.upto_c > c
|
6861
|
-
for
|
7140
|
+
for _, box in self.get_selection_items(
|
6862
7141
|
rows=inc_rows,
|
6863
7142
|
columns=inc_cols,
|
6864
7143
|
)
|
@@ -6868,7 +7147,7 @@ class MainTable(tk.Canvas):
|
|
6868
7147
|
def col_selected(self, c: int, cells: bool = False) -> bool:
|
6869
7148
|
return isinstance(c, int) and any(
|
6870
7149
|
box.coords.from_c <= c and box.coords.upto_c > c
|
6871
|
-
for
|
7150
|
+
for _, box in self.get_selection_items(
|
6872
7151
|
cells=cells,
|
6873
7152
|
rows=False,
|
6874
7153
|
)
|
@@ -6877,7 +7156,7 @@ class MainTable(tk.Canvas):
|
|
6877
7156
|
def row_selected(self, r: int, cells: bool = False) -> bool:
|
6878
7157
|
return isinstance(r, int) and any(
|
6879
7158
|
box.coords.from_r <= r and box.coords.upto_r > r
|
6880
|
-
for
|
7159
|
+
for _, box in self.get_selection_items(
|
6881
7160
|
cells=cells,
|
6882
7161
|
columns=False,
|
6883
7162
|
)
|
@@ -6891,7 +7170,7 @@ class MainTable(tk.Canvas):
|
|
6891
7170
|
) -> list[int]:
|
6892
7171
|
return [
|
6893
7172
|
item
|
6894
|
-
for item,
|
7173
|
+
for item, _ in self.get_selection_items(
|
6895
7174
|
columns=not exclude_columns,
|
6896
7175
|
rows=not exclude_rows,
|
6897
7176
|
cells=not exclude_cells,
|
@@ -6981,7 +7260,7 @@ class MainTable(tk.Canvas):
|
|
6981
7260
|
return False
|
6982
7261
|
self.hide_text_editor()
|
6983
7262
|
if not self.see(r=r, c=c, check_cell_visibility=True):
|
6984
|
-
self.
|
7263
|
+
self.main_table_redraw_grid_and_text(True, True)
|
6985
7264
|
x = self.col_positions[c]
|
6986
7265
|
y = self.row_positions[r]
|
6987
7266
|
w = self.col_positions[c + 1] - x + 1
|
@@ -7049,10 +7328,10 @@ class MainTable(tk.Canvas):
|
|
7049
7328
|
)
|
7050
7329
|
> curr_height
|
7051
7330
|
):
|
7052
|
-
new_height =
|
7053
|
-
|
7054
|
-
|
7055
|
-
|
7331
|
+
new_height = min(
|
7332
|
+
curr_height + self.table_txt_height,
|
7333
|
+
self.scrollregion[3] - self.scrollregion[1] - self.row_positions[r],
|
7334
|
+
)
|
7056
7335
|
if new_height != curr_height:
|
7057
7336
|
self.text_editor.window.config(height=new_height)
|
7058
7337
|
if self.dropdown.open and self.dropdown.get_coords() == (r, c):
|
@@ -7287,10 +7566,8 @@ class MainTable(tk.Canvas):
|
|
7287
7566
|
sheet_h = int(
|
7288
7567
|
self.row_positions[-1] + 1 + self.PAR.ops.empty_vertical - (self.row_positions[r] + text_editor_h)
|
7289
7568
|
)
|
7290
|
-
|
7291
|
-
|
7292
|
-
if sheet_h > 0:
|
7293
|
-
sheet_h -= 1
|
7569
|
+
win_h = max(0, win_h - 1)
|
7570
|
+
sheet_h = max(0, sheet_h - 1)
|
7294
7571
|
return win_h if win_h >= sheet_h else sheet_h
|
7295
7572
|
|
7296
7573
|
def get_dropdown_height_anchor(self, r: int, c: int, text_editor_h: int | None = None) -> tuple:
|
@@ -7299,13 +7576,12 @@ class MainTable(tk.Canvas):
|
|
7299
7576
|
for i, v in enumerate(self.get_cell_kwargs(datarn, datacn, key="dropdown")["values"]):
|
7300
7577
|
v_numlines = len(v.split("\n") if isinstance(v, str) else f"{v}".split("\n"))
|
7301
7578
|
if v_numlines > 1:
|
7302
|
-
win_h +=
|
7579
|
+
win_h += 8 + (v_numlines * self.table_txt_height) # end of cell
|
7303
7580
|
else:
|
7304
7581
|
win_h += self.min_row_height
|
7305
7582
|
if i == 5:
|
7306
7583
|
break
|
7307
|
-
|
7308
|
-
win_h = 500
|
7584
|
+
win_h = min(win_h, 500)
|
7309
7585
|
space_bot = self.get_space_bot(r, text_editor_h)
|
7310
7586
|
space_top = int(self.row_positions[r])
|
7311
7587
|
anchor = "nw"
|
@@ -7395,7 +7671,7 @@ class MainTable(tk.Canvas):
|
|
7395
7671
|
self.itemconfig(self.dropdown.canvas_id, state="normal", anchor=anchor)
|
7396
7672
|
self.dropdown.window.tkraise()
|
7397
7673
|
else:
|
7398
|
-
self.dropdown.window = self.PAR.
|
7674
|
+
self.dropdown.window = self.PAR._dropdown_cls(
|
7399
7675
|
self.winfo_toplevel(),
|
7400
7676
|
**reset_kwargs,
|
7401
7677
|
close_dropdown_window=self.close_dropdown_window,
|
@@ -7440,12 +7716,11 @@ class MainTable(tk.Canvas):
|
|
7440
7716
|
datacn = self.datacn(c)
|
7441
7717
|
datarn = self.datarn(r)
|
7442
7718
|
kwargs = self.get_cell_kwargs(datarn, datacn, key="dropdown")
|
7443
|
-
pre_edit_value = self.get_cell_data(datarn, datacn)
|
7444
7719
|
event_data = event_dict(
|
7445
7720
|
name="end_edit_table",
|
7446
7721
|
sheet=self.PAR.name,
|
7447
7722
|
widget=self,
|
7448
|
-
cells_table={(datarn, datacn):
|
7723
|
+
cells_table={(datarn, datacn): self.get_cell_data(datarn, datacn)},
|
7449
7724
|
key="??",
|
7450
7725
|
value=selection,
|
7451
7726
|
loc=Loc(r, c),
|
@@ -7454,30 +7729,12 @@ class MainTable(tk.Canvas):
|
|
7454
7729
|
boxes=self.get_boxes(),
|
7455
7730
|
selected=self.selected,
|
7456
7731
|
)
|
7457
|
-
|
7458
|
-
|
7459
|
-
if
|
7460
|
-
|
7461
|
-
if
|
7462
|
-
|
7463
|
-
r,
|
7464
|
-
c,
|
7465
|
-
datarn=datarn,
|
7466
|
-
datacn=datacn,
|
7467
|
-
value=selection,
|
7468
|
-
redraw=not redraw,
|
7469
|
-
)
|
7470
|
-
else:
|
7471
|
-
edited = self.set_cell_data_undo(
|
7472
|
-
r,
|
7473
|
-
c,
|
7474
|
-
datarn=datarn,
|
7475
|
-
datacn=datacn,
|
7476
|
-
value=selection,
|
7477
|
-
redraw=not redraw,
|
7478
|
-
)
|
7479
|
-
if edited:
|
7480
|
-
try_binding(self.extra_end_edit_cell_func, event_data)
|
7732
|
+
try_binding(kwargs["select_function"], event_data)
|
7733
|
+
selection = selection if not self.edit_validation_func else self.edit_validation_func(event_data)
|
7734
|
+
if selection is not None:
|
7735
|
+
edited = self.set_cell_data_undo(r, c, datarn=datarn, datacn=datacn, value=selection, redraw=not redraw)
|
7736
|
+
if edited:
|
7737
|
+
try_binding(self.extra_end_edit_cell_func, event_data)
|
7481
7738
|
self.recreate_all_selection_boxes()
|
7482
7739
|
self.focus_set()
|
7483
7740
|
self.hide_text_editor_and_dropdown(redraw=redraw)
|
@@ -7770,7 +8027,7 @@ class MainTable(tk.Canvas):
|
|
7770
8027
|
else:
|
7771
8028
|
# assumed given formatter class has get_data_with_valid_check()
|
7772
8029
|
return f"{value.get_data_with_valid_check()}"
|
7773
|
-
return "" if value is None else f"{value}"
|
8030
|
+
return "" if value is None else value if isinstance(value, str) else f"{value}"
|
7774
8031
|
|
7775
8032
|
def get_cell_data(
|
7776
8033
|
self,
|
@@ -7783,7 +8040,11 @@ class MainTable(tk.Canvas):
|
|
7783
8040
|
) -> object:
|
7784
8041
|
if get_displayed:
|
7785
8042
|
return self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
|
7786
|
-
value =
|
8043
|
+
value = (
|
8044
|
+
self.data[datarn][datacn]
|
8045
|
+
if len(self.data) > datarn and len(self.data[datarn]) > datacn
|
8046
|
+
else self.get_value_for_empty_cell(datarn, datacn)
|
8047
|
+
)
|
7787
8048
|
kwargs = self.get_cell_kwargs(datarn, datacn, key="format")
|
7788
8049
|
if kwargs and kwargs["formatter"] is not None:
|
7789
8050
|
value = value.value # assumed given formatter class has value attribute
|