tksheet 7.3.4__py3-none-any.whl → 7.4.1__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/column_headers.py +328 -239
- tksheet/constants.py +13 -0
- tksheet/functions.py +194 -11
- tksheet/main_table.py +957 -583
- tksheet/other_classes.py +12 -8
- tksheet/row_index.py +830 -259
- tksheet/sheet.py +465 -589
- tksheet/sheet_options.py +44 -1
- tksheet/sorting.py +287 -0
- tksheet/text_editor.py +2 -6
- tksheet/{types.py → tksheet_types.py} +10 -1
- {tksheet-7.3.4.dist-info → tksheet-7.4.1.dist-info}/METADATA +13 -16
- tksheet-7.4.1.dist-info/RECORD +22 -0
- tksheet-7.3.4.dist-info/RECORD +0 -21
- {tksheet-7.3.4.dist-info → tksheet-7.4.1.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.3.4.dist-info → tksheet-7.4.1.dist-info}/WHEEL +0 -0
- {tksheet-7.3.4.dist-info → tksheet-7.4.1.dist-info}/top_level.txt +0 -0
tksheet/main_table.py
CHANGED
@@ -14,13 +14,16 @@ from tkinter import TclError
|
|
14
14
|
from typing import Literal
|
15
15
|
|
16
16
|
from .colors import color_map
|
17
|
+
from .column_headers import ColumnHeaders
|
17
18
|
from .constants import (
|
18
19
|
USER_OS,
|
20
|
+
_test_str,
|
19
21
|
bind_add_columns,
|
20
22
|
bind_add_rows,
|
21
23
|
bind_del_columns,
|
22
24
|
bind_del_rows,
|
23
25
|
ctrl_key,
|
26
|
+
font_value_error,
|
24
27
|
rc_binding,
|
25
28
|
text_editor_close_bindings,
|
26
29
|
text_editor_newline_bindings,
|
@@ -45,6 +48,7 @@ from .functions import (
|
|
45
48
|
cell_right_within_box,
|
46
49
|
color_tup,
|
47
50
|
consecutive_ranges,
|
51
|
+
data_to_displayed_idxs,
|
48
52
|
diff_gen,
|
49
53
|
diff_list,
|
50
54
|
down_cell_within_box,
|
@@ -70,11 +74,13 @@ from .functions import (
|
|
70
74
|
move_elements_by_mapping,
|
71
75
|
new_tk_event,
|
72
76
|
next_cell,
|
77
|
+
push_n,
|
73
78
|
rounded_box_coords,
|
74
79
|
span_idxs_post_move,
|
75
80
|
stored_event_dict,
|
76
81
|
try_binding,
|
77
82
|
unpickle_obj,
|
83
|
+
wrap_text,
|
78
84
|
)
|
79
85
|
from .other_classes import (
|
80
86
|
Box_nt,
|
@@ -92,20 +98,30 @@ from .other_classes import (
|
|
92
98
|
SelectionBox,
|
93
99
|
TextEditorStorage,
|
94
100
|
)
|
101
|
+
from .row_index import RowIndex
|
102
|
+
from .sorting import sort_selection
|
95
103
|
from .text_editor import TextEditor
|
96
|
-
from .
|
104
|
+
from .tksheet_types import AnyIter
|
97
105
|
|
98
106
|
|
99
107
|
class MainTable(tk.Canvas):
|
100
|
-
def __init__(
|
108
|
+
def __init__(
|
109
|
+
self,
|
110
|
+
parent,
|
111
|
+
row_index_canvas: RowIndex,
|
112
|
+
column_headers_canvas: ColumnHeaders,
|
113
|
+
**kwargs,
|
114
|
+
):
|
101
115
|
super().__init__(
|
102
|
-
|
103
|
-
background=
|
116
|
+
parent,
|
117
|
+
background=parent.ops.table_bg,
|
104
118
|
highlightthickness=0,
|
105
119
|
)
|
106
|
-
self.PAR =
|
120
|
+
self.PAR = parent
|
107
121
|
self.PAR_width = 0
|
108
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
|
109
125
|
self.scrollregion = tuple()
|
110
126
|
self.current_cursor = ""
|
111
127
|
self.ctrl_b1_pressed = False
|
@@ -176,6 +192,9 @@ class MainTable(tk.Canvas):
|
|
176
192
|
|
177
193
|
self.edit_validation_func = None
|
178
194
|
|
195
|
+
self.extra_begin_sort_cells_func = None
|
196
|
+
self.extra_end_sort_cells_func = None
|
197
|
+
|
179
198
|
self.extra_begin_ctrl_c_func = None
|
180
199
|
self.extra_end_ctrl_c_func = None
|
181
200
|
|
@@ -239,50 +258,48 @@ class MainTable(tk.Canvas):
|
|
239
258
|
self.rc_insert_column_enabled = False
|
240
259
|
self.rc_delete_row_enabled = False
|
241
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
|
242
266
|
self.rc_popup_menus_enabled = False
|
243
267
|
self.edit_cell_enabled = False
|
244
|
-
self.CH =
|
268
|
+
self.CH = column_headers_canvas
|
245
269
|
self.CH.MT = self
|
246
|
-
self.CH.RI =
|
247
|
-
self.RI =
|
270
|
+
self.CH.RI = row_index_canvas
|
271
|
+
self.RI = row_index_canvas
|
248
272
|
self.RI.MT = self
|
249
|
-
self.RI.CH =
|
273
|
+
self.RI.CH = column_headers_canvas
|
250
274
|
self.TL = None # is set from within TopLeftRectangle() __init__
|
251
275
|
self.all_columns_displayed = True
|
252
276
|
self.all_rows_displayed = True
|
253
277
|
self.align = kwargs["align"]
|
254
|
-
|
255
|
-
self.PAR.ops.table_font = [
|
278
|
+
self.PAR.ops.table_font = FontTuple(
|
256
279
|
self.PAR.ops.table_font[0],
|
257
|
-
int(self.PAR.ops.table_font[1] * kwargs["zoom"] / 100),
|
280
|
+
max(1, int(self.PAR.ops.table_font[1] * kwargs["zoom"] / 100)),
|
258
281
|
self.PAR.ops.table_font[2],
|
259
|
-
|
260
|
-
|
261
|
-
self.PAR.ops.index_font = [
|
282
|
+
)
|
283
|
+
self.PAR.ops.index_font = FontTuple(
|
262
284
|
self.PAR.ops.index_font[0],
|
263
|
-
int(self.PAR.ops.index_font[1] * kwargs["zoom"] / 100),
|
285
|
+
max(1, int(self.PAR.ops.index_font[1] * kwargs["zoom"] / 100)),
|
264
286
|
self.PAR.ops.index_font[2],
|
265
|
-
|
266
|
-
|
267
|
-
self.PAR.ops.header_font = [
|
287
|
+
)
|
288
|
+
self.PAR.ops.header_font = FontTuple(
|
268
289
|
self.PAR.ops.header_font[0],
|
269
|
-
int(self.PAR.ops.header_font[1] * kwargs["zoom"] / 100),
|
290
|
+
max(1, int(self.PAR.ops.header_font[1] * kwargs["zoom"] / 100)),
|
270
291
|
self.PAR.ops.header_font[2],
|
271
|
-
|
272
|
-
for fnt in (self.PAR.ops.table_font, self.PAR.ops.index_font, self.PAR.ops.header_font):
|
273
|
-
if fnt[1] < 1:
|
274
|
-
fnt[1] = 1
|
275
|
-
self.PAR.ops.table_font = FontTuple(*self.PAR.ops.table_font)
|
276
|
-
self.PAR.ops.index_font = FontTuple(*self.PAR.ops.index_font)
|
277
|
-
self.PAR.ops.header_font = FontTuple(*self.PAR.ops.header_font)
|
278
|
-
|
292
|
+
)
|
279
293
|
self.txt_measure_canvas = tk.Canvas(self)
|
280
294
|
self.txt_measure_canvas_text = self.txt_measure_canvas.create_text(0, 0, text="", font=self.PAR.ops.table_font)
|
281
295
|
|
282
296
|
self.RI.set_width(self.PAR.ops.default_row_index_width)
|
297
|
+
|
298
|
+
self.char_widths = {}
|
283
299
|
self.set_table_font_help()
|
284
300
|
self.set_header_font_help()
|
285
301
|
self.set_index_font_help()
|
302
|
+
|
286
303
|
self.data = kwargs["data_reference"]
|
287
304
|
if isinstance(self.data, (list, tuple)):
|
288
305
|
self.data = kwargs["data_reference"]
|
@@ -344,7 +361,7 @@ class MainTable(tk.Canvas):
|
|
344
361
|
super().event_generate(*args, **kwargs)
|
345
362
|
|
346
363
|
def refresh(self, event: object = None) -> None:
|
347
|
-
self.
|
364
|
+
self.PAR.set_refresh_timer()
|
348
365
|
|
349
366
|
def window_configured(self, event: object) -> None:
|
350
367
|
w = self.PAR.winfo_width()
|
@@ -450,7 +467,7 @@ class MainTable(tk.Canvas):
|
|
450
467
|
dash=dash,
|
451
468
|
width=3,
|
452
469
|
outline=self.PAR.ops.resizing_line_fg if outline is None else outline,
|
453
|
-
|
470
|
+
tags="ctrl",
|
454
471
|
)
|
455
472
|
if delete_on_timer:
|
456
473
|
self.after(1500, self.delete_ctrl_outlines)
|
@@ -711,13 +728,13 @@ class MainTable(tk.Canvas):
|
|
711
728
|
dash: tuple[int, int],
|
712
729
|
width: int,
|
713
730
|
outline: str,
|
714
|
-
|
731
|
+
tags: str | tuple[str, ...],
|
715
732
|
) -> None:
|
716
733
|
if self.hidd_ctrl_outline:
|
717
734
|
t, sh = self.hidd_ctrl_outline.popitem()
|
718
735
|
self.coords(t, x1, y1, x2, y2)
|
719
736
|
if sh:
|
720
|
-
self.itemconfig(t, fill=fill, dash=dash, width=width, outline=outline,
|
737
|
+
self.itemconfig(t, fill=fill, dash=dash, width=width, outline=outline, tags=tags)
|
721
738
|
else:
|
722
739
|
self.itemconfig(
|
723
740
|
t,
|
@@ -725,7 +742,7 @@ class MainTable(tk.Canvas):
|
|
725
742
|
dash=dash,
|
726
743
|
width=width,
|
727
744
|
outline=outline,
|
728
|
-
|
745
|
+
tags=tags,
|
729
746
|
state="normal",
|
730
747
|
)
|
731
748
|
self.lift(t)
|
@@ -739,7 +756,7 @@ class MainTable(tk.Canvas):
|
|
739
756
|
dash=dash,
|
740
757
|
width=width,
|
741
758
|
outline=outline,
|
742
|
-
|
759
|
+
tags=tags,
|
743
760
|
)
|
744
761
|
self.disp_ctrl_outline[t] = True
|
745
762
|
|
@@ -778,15 +795,20 @@ class MainTable(tk.Canvas):
|
|
778
795
|
)
|
779
796
|
return s, writer
|
780
797
|
|
781
|
-
def
|
782
|
-
|
783
|
-
|
784
|
-
event_data = event_dict(
|
785
|
-
name="begin_ctrl_c",
|
798
|
+
def new_event_dict(self, name: str, boxes: dict | None = None, state: bool = False) -> EventDataDict:
|
799
|
+
return event_dict(
|
800
|
+
name=name,
|
786
801
|
sheet=self.PAR.name,
|
787
802
|
widget=self,
|
803
|
+
boxes=self.get_boxes() if boxes is None else boxes,
|
788
804
|
selected=self.selected,
|
805
|
+
sheet_state=self.copy_sheet_state() if state else None,
|
789
806
|
)
|
807
|
+
|
808
|
+
def ctrl_c(self, event=None) -> None | EventDataDict:
|
809
|
+
if not self.selected:
|
810
|
+
return
|
811
|
+
event_data = self.new_event_dict("begin_ctrl_c")
|
790
812
|
boxes, maxrows = self.get_ctrl_x_c_boxes()
|
791
813
|
event_data["selection_boxes"] = boxes
|
792
814
|
s, writer = self.io_csv_writer()
|
@@ -831,12 +853,7 @@ class MainTable(tk.Canvas):
|
|
831
853
|
def ctrl_x(self, event=None, validation: bool = True) -> None | EventDataDict:
|
832
854
|
if not self.selected:
|
833
855
|
return
|
834
|
-
event_data =
|
835
|
-
name="edit_table",
|
836
|
-
sheet=self.PAR.name,
|
837
|
-
widget=self,
|
838
|
-
selected=self.selected,
|
839
|
-
)
|
856
|
+
event_data = self.new_event_dict("edit_table")
|
840
857
|
boxes, maxrows = self.get_ctrl_x_c_boxes()
|
841
858
|
event_data["selection_boxes"] = boxes
|
842
859
|
s, writer = self.io_csv_writer()
|
@@ -912,17 +929,64 @@ class MainTable(tk.Canvas):
|
|
912
929
|
self.PAR.emit_event("<<Cut>>", event_data)
|
913
930
|
return event_data
|
914
931
|
|
932
|
+
def sort_boxes(
|
933
|
+
self,
|
934
|
+
event: tk.Event | None = None,
|
935
|
+
boxes: AnyIter[int, int, int, int] | None = None,
|
936
|
+
reverse: bool = False,
|
937
|
+
row_wise: bool = False,
|
938
|
+
validation: bool = True,
|
939
|
+
key: Callable | None = None,
|
940
|
+
undo: bool = True,
|
941
|
+
) -> EventDataDict:
|
942
|
+
if boxes is None:
|
943
|
+
boxes = self.get_boxes()
|
944
|
+
if not boxes:
|
945
|
+
boxes = [(0, 0, len(self.row_positions) - 1, len(self.col_positions) - 1)]
|
946
|
+
event_data = self.new_event_dict("edit_table", boxes=boxes)
|
947
|
+
try_binding(self.extra_begin_sort_cells_func, event_data)
|
948
|
+
for r1, c1, r2, c2 in boxes:
|
949
|
+
data = sort_selection(
|
950
|
+
[[self.get_cell_data(self.datarn(r), self.datacn(c)) for c in range(c1, c2)] for r in range(r1, r2)],
|
951
|
+
reverse=reverse,
|
952
|
+
key=key,
|
953
|
+
row_wise=row_wise,
|
954
|
+
)
|
955
|
+
for ir, r in enumerate(range(r1, r2)):
|
956
|
+
data_r = self.datarn(r)
|
957
|
+
for ic, c in enumerate(range(c1, c2)):
|
958
|
+
data_c = self.datacn(c)
|
959
|
+
val = data[ir][ic]
|
960
|
+
if (
|
961
|
+
not self.edit_validation_func
|
962
|
+
or not validation
|
963
|
+
or (
|
964
|
+
self.edit_validation_func
|
965
|
+
and (val := self.edit_validation_func(mod_event_val(event_data, val, (data_r, data_c))))
|
966
|
+
is not None
|
967
|
+
)
|
968
|
+
):
|
969
|
+
event_data = self.event_data_set_cell(
|
970
|
+
datarn=data_r,
|
971
|
+
datacn=data_c,
|
972
|
+
value=val,
|
973
|
+
event_data=event_data,
|
974
|
+
)
|
975
|
+
if event_data["cells"]["table"]:
|
976
|
+
if undo and self.undo_enabled:
|
977
|
+
self.undo_stack.append(stored_event_dict(event_data))
|
978
|
+
try_binding(self.extra_end_sort_cells_func, event_data, "end_edit_table")
|
979
|
+
self.sheet_modified(event_data)
|
980
|
+
self.PAR.emit_event("<<SheetModified>>", event_data)
|
981
|
+
self.refresh()
|
982
|
+
return event_data
|
983
|
+
|
915
984
|
def ctrl_v(self, event: object = None, validation: bool = True) -> None | EventDataDict:
|
916
985
|
if not self.PAR.ops.paste_can_expand_x and len(self.col_positions) == 1:
|
917
986
|
return
|
918
987
|
if not self.PAR.ops.paste_can_expand_y and len(self.row_positions) == 1:
|
919
988
|
return
|
920
|
-
event_data =
|
921
|
-
name="edit_table",
|
922
|
-
sheet=self.PAR.name,
|
923
|
-
widget=self,
|
924
|
-
selected=self.selected,
|
925
|
-
)
|
989
|
+
event_data = self.new_event_dict("edit_table", state=True)
|
926
990
|
if self.selected:
|
927
991
|
selected_r = self.selected.box.from_r
|
928
992
|
selected_c = self.selected.box.from_c
|
@@ -1081,7 +1145,7 @@ class MainTable(tk.Canvas):
|
|
1081
1145
|
if ctr:
|
1082
1146
|
event_data = self.add_rows(
|
1083
1147
|
rows=rows,
|
1084
|
-
index=index,
|
1148
|
+
index=index if isinstance(self._row_index, list) and self._row_index else {},
|
1085
1149
|
row_heights=row_heights,
|
1086
1150
|
event_data=event_data,
|
1087
1151
|
mod_event_boxes=False,
|
@@ -1131,7 +1195,7 @@ class MainTable(tk.Canvas):
|
|
1131
1195
|
if ctr:
|
1132
1196
|
event_data = self.add_columns(
|
1133
1197
|
columns=columns,
|
1134
|
-
header=headers,
|
1198
|
+
header=headers if isinstance(self._headers, list) and self._headers else {},
|
1135
1199
|
column_widths=column_widths,
|
1136
1200
|
event_data=event_data,
|
1137
1201
|
mod_event_boxes=False,
|
@@ -1179,12 +1243,7 @@ class MainTable(tk.Canvas):
|
|
1179
1243
|
def delete_key(self, event: object = None, validation: bool = True) -> None | EventDataDict:
|
1180
1244
|
if not self.selected:
|
1181
1245
|
return
|
1182
|
-
event_data =
|
1183
|
-
name="edit_table",
|
1184
|
-
sheet=self.PAR.name,
|
1185
|
-
widget=self,
|
1186
|
-
selected=self.selected,
|
1187
|
-
)
|
1246
|
+
event_data = self.new_event_dict("edit_table")
|
1188
1247
|
boxes = self.get_boxes()
|
1189
1248
|
event_data["selection_boxes"] = boxes
|
1190
1249
|
if not try_binding(self.extra_begin_delete_key_func, event_data, "begin_delete"):
|
@@ -1259,7 +1318,6 @@ class MainTable(tk.Canvas):
|
|
1259
1318
|
move_data: bool = True,
|
1260
1319
|
move_widths: bool = True,
|
1261
1320
|
create_selections: bool = True,
|
1262
|
-
data_indexes: bool = False,
|
1263
1321
|
event_data: EventDataDict | None = None,
|
1264
1322
|
) -> tuple[dict[int, int], dict[int, int], EventDataDict]:
|
1265
1323
|
self.saved_column_widths = {}
|
@@ -1268,22 +1326,17 @@ class MainTable(tk.Canvas):
|
|
1268
1326
|
if totalcols:
|
1269
1327
|
totalcols += 1
|
1270
1328
|
totalcols = self.equalize_data_row_lengths(at_least_cols=totalcols)
|
1271
|
-
if event_data
|
1272
|
-
event_data =
|
1273
|
-
|
1274
|
-
sheet=self.PAR.name,
|
1275
|
-
widget=self,
|
1276
|
-
boxes=self.get_boxes(),
|
1277
|
-
selected=self.selected,
|
1278
|
-
)
|
1329
|
+
if not event_data:
|
1330
|
+
event_data = self.new_event_dict("move_columns", state=True)
|
1331
|
+
if not event_data["moved"]["columns"]:
|
1279
1332
|
event_data["moved"]["columns"] = {
|
1280
1333
|
"data": data_new_idxs,
|
1281
1334
|
"displayed": {} if disp_new_idxs is None else disp_new_idxs,
|
1282
1335
|
}
|
1283
1336
|
event_data["options"] = self.copy_options()
|
1284
1337
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
1285
|
-
|
1286
|
-
|
1338
|
+
|
1339
|
+
if move_widths and disp_new_idxs:
|
1287
1340
|
self.set_col_positions(
|
1288
1341
|
itr=move_elements_by_mapping(
|
1289
1342
|
self.get_column_widths(),
|
@@ -1297,6 +1350,7 @@ class MainTable(tk.Canvas):
|
|
1297
1350
|
)
|
1298
1351
|
)
|
1299
1352
|
if create_selections:
|
1353
|
+
self.deselect("all", run_binding=False, redraw=False)
|
1300
1354
|
for boxst, boxend in consecutive_ranges(sorted(disp_new_idxs.values())):
|
1301
1355
|
self.create_selection_box(
|
1302
1356
|
0,
|
@@ -1306,6 +1360,8 @@ class MainTable(tk.Canvas):
|
|
1306
1360
|
"columns",
|
1307
1361
|
run_binding=True,
|
1308
1362
|
)
|
1363
|
+
else:
|
1364
|
+
self.recreate_all_selection_boxes()
|
1309
1365
|
if move_data:
|
1310
1366
|
self.data = list(
|
1311
1367
|
map(
|
@@ -1459,29 +1515,54 @@ class MainTable(tk.Canvas):
|
|
1459
1515
|
data_indexes: bool = False,
|
1460
1516
|
) -> tuple[dict[int, int], dict[int, int], int, dict[int, int]]:
|
1461
1517
|
if not data_indexes or self.all_rows_displayed:
|
1462
|
-
disp_new_idxs = get_new_indexes(
|
1518
|
+
disp_new_idxs = get_new_indexes(
|
1519
|
+
move_to=move_to,
|
1520
|
+
to_move=to_move,
|
1521
|
+
)
|
1522
|
+
data_new_idxs = dict(disp_new_idxs)
|
1463
1523
|
else:
|
1464
1524
|
disp_new_idxs = {}
|
1525
|
+
data_new_idxs = get_new_indexes(
|
1526
|
+
move_to=move_to,
|
1527
|
+
to_move=to_move,
|
1528
|
+
)
|
1465
1529
|
# move_to can be len and fix_data_len() takes index so - 1
|
1466
1530
|
fix_len = (move_to - 1) if move_to else move_to
|
1467
1531
|
if not self.all_rows_displayed and not data_indexes:
|
1468
1532
|
fix_len = self.datarn(fix_len)
|
1469
1533
|
self.fix_data_len(fix_len)
|
1470
1534
|
totalrows = max(self.total_data_rows(), len(self.row_positions) - 1)
|
1471
|
-
data_new_idxs = get_new_indexes(move_to=move_to, to_move=to_move)
|
1472
1535
|
if not self.all_rows_displayed and not data_indexes:
|
1473
|
-
|
1474
|
-
|
1536
|
+
keep = set(map(self.datarn, to_move))
|
1537
|
+
data_new_idxs = {
|
1538
|
+
k: v
|
1539
|
+
for k, v in zip(
|
1475
1540
|
move_elements_by_mapping(
|
1476
1541
|
self.displayed_rows,
|
1477
1542
|
data_new_idxs,
|
1478
1543
|
dict(zip(data_new_idxs.values(), data_new_idxs)),
|
1479
1544
|
),
|
1480
1545
|
self.displayed_rows,
|
1481
|
-
)
|
1482
|
-
|
1546
|
+
)
|
1547
|
+
if k in keep
|
1548
|
+
}
|
1483
1549
|
return data_new_idxs, dict(zip(data_new_idxs.values(), data_new_idxs)), totalrows, disp_new_idxs
|
1484
1550
|
|
1551
|
+
def move_rows_data(
|
1552
|
+
self,
|
1553
|
+
data_new_idxs: dict[int, int],
|
1554
|
+
data_old_idxs: dict[int, int],
|
1555
|
+
maxidx: int,
|
1556
|
+
) -> None:
|
1557
|
+
self.data = move_elements_by_mapping(
|
1558
|
+
self.data,
|
1559
|
+
data_new_idxs,
|
1560
|
+
data_old_idxs,
|
1561
|
+
)
|
1562
|
+
self.RI.fix_index(maxidx)
|
1563
|
+
if isinstance(self._row_index, list) and self._row_index:
|
1564
|
+
self._row_index = move_elements_by_mapping(self._row_index, data_new_idxs, data_old_idxs)
|
1565
|
+
|
1485
1566
|
def move_rows_adjust_options_dict(
|
1486
1567
|
self,
|
1487
1568
|
data_new_idxs: dict[int, int],
|
@@ -1491,8 +1572,9 @@ class MainTable(tk.Canvas):
|
|
1491
1572
|
move_data: bool = True,
|
1492
1573
|
move_heights: bool = True,
|
1493
1574
|
create_selections: bool = True,
|
1494
|
-
data_indexes: bool = False,
|
1495
1575
|
event_data: EventDataDict | None = None,
|
1576
|
+
undo_modification: EventDataDict | None = None,
|
1577
|
+
node_change: None | tuple[str, str, int] = None,
|
1496
1578
|
) -> tuple[dict[int, int], dict[int, int], EventDataDict]:
|
1497
1579
|
self.saved_row_heights = {}
|
1498
1580
|
if not isinstance(totalrows, int):
|
@@ -1502,54 +1584,33 @@ class MainTable(tk.Canvas):
|
|
1502
1584
|
max(data_new_idxs.values(), default=0),
|
1503
1585
|
)
|
1504
1586
|
self.fix_data_len(totalrows - 1)
|
1505
|
-
if event_data
|
1506
|
-
event_data =
|
1507
|
-
|
1508
|
-
sheet=self.PAR.name,
|
1509
|
-
widget=self,
|
1510
|
-
boxes=self.get_boxes(),
|
1511
|
-
selected=self.selected,
|
1512
|
-
)
|
1587
|
+
if not event_data:
|
1588
|
+
event_data = self.new_event_dict("move_rows", state=True)
|
1589
|
+
if not event_data["moved"]["rows"]:
|
1513
1590
|
event_data["moved"]["rows"] = {
|
1514
1591
|
"data": data_new_idxs,
|
1515
1592
|
"displayed": {} if disp_new_idxs is None else disp_new_idxs,
|
1516
1593
|
}
|
1517
1594
|
event_data["options"] = self.copy_options()
|
1518
1595
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
1519
|
-
|
1520
|
-
self.deselect("all", run_binding=False, redraw=False)
|
1521
|
-
self.set_row_positions(
|
1522
|
-
itr=move_elements_by_mapping(
|
1523
|
-
self.get_row_heights(),
|
1524
|
-
disp_new_idxs,
|
1525
|
-
dict(
|
1526
|
-
zip(
|
1527
|
-
disp_new_idxs.values(),
|
1528
|
-
disp_new_idxs,
|
1529
|
-
)
|
1530
|
-
),
|
1531
|
-
)
|
1532
|
-
)
|
1533
|
-
if create_selections:
|
1534
|
-
for boxst, boxend in consecutive_ranges(sorted(disp_new_idxs.values())):
|
1535
|
-
self.create_selection_box(
|
1536
|
-
boxst,
|
1537
|
-
0,
|
1538
|
-
boxend,
|
1539
|
-
len(self.col_positions) - 1,
|
1540
|
-
"rows",
|
1541
|
-
run_binding=True,
|
1542
|
-
)
|
1596
|
+
|
1543
1597
|
if move_data:
|
1544
|
-
self.data = move_elements_by_mapping(
|
1545
|
-
self.data,
|
1546
|
-
data_new_idxs,
|
1547
|
-
data_old_idxs,
|
1548
|
-
)
|
1549
1598
|
maxidx = len_to_idx(totalrows)
|
1550
|
-
self.
|
1551
|
-
|
1552
|
-
|
1599
|
+
if self.PAR.ops.treeview:
|
1600
|
+
two_step_move = self.RI.move_rows_mod_nodes(
|
1601
|
+
data_new_idxs=data_new_idxs,
|
1602
|
+
data_old_idxs=data_old_idxs,
|
1603
|
+
disp_new_idxs=disp_new_idxs,
|
1604
|
+
maxidx=maxidx,
|
1605
|
+
event_data=event_data,
|
1606
|
+
undo_modification=undo_modification,
|
1607
|
+
node_change=node_change,
|
1608
|
+
)
|
1609
|
+
data_new_idxs, data_old_idxs, disp_new_idxs, event_data = next(two_step_move)
|
1610
|
+
if not data_new_idxs and not disp_new_idxs:
|
1611
|
+
return data_new_idxs, disp_new_idxs, event_data
|
1612
|
+
else:
|
1613
|
+
self.move_rows_data(data_new_idxs, data_old_idxs, maxidx)
|
1553
1614
|
maxidx = self.get_max_row_idx(maxidx)
|
1554
1615
|
full_new_idxs = self.get_full_new_idxs(
|
1555
1616
|
max_idx=maxidx,
|
@@ -1567,6 +1628,9 @@ class MainTable(tk.Canvas):
|
|
1567
1628
|
self.RI.cell_options = {full_new_idxs[k]: v for k, v in self.RI.cell_options.items()}
|
1568
1629
|
self.RI.tree_rns = {v: full_new_idxs[k] for v, k in self.RI.tree_rns.items()}
|
1569
1630
|
self.displayed_rows = sorted(full_new_idxs[k] for k in self.displayed_rows)
|
1631
|
+
if self.PAR.ops.treeview:
|
1632
|
+
next(two_step_move)
|
1633
|
+
|
1570
1634
|
if self.named_spans:
|
1571
1635
|
totalcols = self.total_data_cols()
|
1572
1636
|
new_ops = self.PAR.create_options_from_span
|
@@ -1665,6 +1729,33 @@ class MainTable(tk.Canvas):
|
|
1665
1729
|
del self.cell_options[(full_new_idxs[k], c)][span["type_"]]
|
1666
1730
|
# finally, change the span coords
|
1667
1731
|
span["from_r"], span["upto_r"] = newfrom, newupto
|
1732
|
+
|
1733
|
+
if move_heights and disp_new_idxs:
|
1734
|
+
self.set_row_positions(
|
1735
|
+
itr=move_elements_by_mapping(
|
1736
|
+
self.get_row_heights(),
|
1737
|
+
disp_new_idxs,
|
1738
|
+
dict(
|
1739
|
+
zip(
|
1740
|
+
disp_new_idxs.values(),
|
1741
|
+
disp_new_idxs,
|
1742
|
+
)
|
1743
|
+
),
|
1744
|
+
)
|
1745
|
+
)
|
1746
|
+
if create_selections:
|
1747
|
+
self.deselect("all", run_binding=False, redraw=False)
|
1748
|
+
for boxst, boxend in consecutive_ranges(sorted(disp_new_idxs.values())):
|
1749
|
+
self.create_selection_box(
|
1750
|
+
boxst,
|
1751
|
+
0,
|
1752
|
+
boxend,
|
1753
|
+
len(self.col_positions) - 1,
|
1754
|
+
"rows",
|
1755
|
+
run_binding=True,
|
1756
|
+
)
|
1757
|
+
else:
|
1758
|
+
self.recreate_all_selection_boxes()
|
1668
1759
|
return data_new_idxs, disp_new_idxs, event_data
|
1669
1760
|
|
1670
1761
|
def get_max_row_idx(self, maxidx: int | None = None) -> int:
|
@@ -1781,7 +1872,7 @@ class MainTable(tk.Canvas):
|
|
1781
1872
|
event_data["cells"]["table"][k] = self.get_cell_data(k[0], k[1])
|
1782
1873
|
return event_data
|
1783
1874
|
|
1784
|
-
def
|
1875
|
+
def restore_sheet_state(self, modification: EventDataDict) -> None:
|
1785
1876
|
if "cell_options" in modification["options"]:
|
1786
1877
|
self.cell_options = modification["options"]["cell_options"]
|
1787
1878
|
if "column_options" in modification["options"]:
|
@@ -1798,17 +1889,25 @@ class MainTable(tk.Canvas):
|
|
1798
1889
|
self.tagged_rows = modification["options"]["tagged_rows"]
|
1799
1890
|
if "tagged_columns" in modification["options"]:
|
1800
1891
|
self.tagged_columns = modification["options"]["tagged_columns"]
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1892
|
+
if modification["named_spans"]:
|
1893
|
+
self.named_spans = {
|
1894
|
+
k: mod_span_widget(unpickle_obj(v), self.PAR) for k, v in modification["named_spans"].items()
|
1895
|
+
}
|
1896
|
+
if modification["sheet_state"]:
|
1897
|
+
self.RI.tree_open_ids = modification["sheet_state"]["tree_open_ids"]
|
1898
|
+
self.row_positions = modification["sheet_state"]["row_positions"]
|
1899
|
+
self.col_positions = modification["sheet_state"]["col_positions"]
|
1900
|
+
self.displayed_rows = modification["sheet_state"]["displayed_rows"]
|
1901
|
+
self.displayed_columns = modification["sheet_state"]["displayed_columns"]
|
1902
|
+
self.all_rows_displayed = modification["sheet_state"]["all_rows_displayed"]
|
1903
|
+
self.all_columns_displayed = modification["sheet_state"]["all_columns_displayed"]
|
1904
|
+
self.saved_row_heights = modification["sheet_state"]["saved_row_heights"]
|
1905
|
+
self.saved_column_widths = modification["sheet_state"]["saved_column_widths"]
|
1906
|
+
self.recreate_all_selection_boxes()
|
1804
1907
|
|
1805
1908
|
def undo_modification_invert_event(self, modification: EventDataDict, name: str = "undo") -> EventDataDict:
|
1806
1909
|
self.deselect("all", redraw=False)
|
1807
|
-
event_data =
|
1808
|
-
name=modification["eventname"],
|
1809
|
-
sheet=self.PAR.name,
|
1810
|
-
widget=self,
|
1811
|
-
)
|
1910
|
+
event_data = self.new_event_dict(modification["eventname"], state=True)
|
1812
1911
|
event_data["selection_boxes"] = modification["selection_boxes"]
|
1813
1912
|
event_data["selected"] = modification["selected"]
|
1814
1913
|
saved_cells = False
|
@@ -1839,7 +1938,6 @@ class MainTable(tk.Canvas):
|
|
1839
1938
|
"data": data_new_idxs,
|
1840
1939
|
"displayed": disp_new_idxs,
|
1841
1940
|
}
|
1842
|
-
self.restore_options_named_spans(modification)
|
1843
1941
|
|
1844
1942
|
if modification["moved"]["rows"]:
|
1845
1943
|
totalrows = max(self.total_data_rows(), max(modification["moved"]["rows"]["data"].values()))
|
@@ -1859,12 +1957,12 @@ class MainTable(tk.Canvas):
|
|
1859
1957
|
)
|
1860
1958
|
),
|
1861
1959
|
event_data=event_data,
|
1960
|
+
undo_modification=modification,
|
1862
1961
|
)
|
1863
1962
|
event_data["moved"]["rows"] = {
|
1864
1963
|
"data": data_new_idxs,
|
1865
1964
|
"displayed": disp_new_idxs,
|
1866
1965
|
}
|
1867
|
-
self.restore_options_named_spans(modification)
|
1868
1966
|
|
1869
1967
|
if modification["added"]["rows"]:
|
1870
1968
|
self.deselect("all", run_binding=False, redraw=False)
|
@@ -1875,8 +1973,8 @@ class MainTable(tk.Canvas):
|
|
1875
1973
|
event_data = self.delete_rows_displayed(
|
1876
1974
|
rows=tuple(reversed(modification["added"]["rows"]["row_heights"])),
|
1877
1975
|
event_data=event_data,
|
1976
|
+
restored_state=True,
|
1878
1977
|
)
|
1879
|
-
self.displayed_rows = modification["added"]["rows"]["displayed_rows"]
|
1880
1978
|
|
1881
1979
|
if modification["added"]["columns"]:
|
1882
1980
|
self.deselect("all", run_binding=False, redraw=False)
|
@@ -1887,21 +1985,21 @@ class MainTable(tk.Canvas):
|
|
1887
1985
|
event_data = self.delete_columns_displayed(
|
1888
1986
|
cols=tuple(reversed(modification["added"]["columns"]["column_widths"])),
|
1889
1987
|
event_data=event_data,
|
1988
|
+
restored_state=True,
|
1890
1989
|
)
|
1891
|
-
self.displayed_columns = modification["added"]["columns"]["displayed_columns"]
|
1892
1990
|
|
1893
1991
|
if modification["deleted"]["rows"] or modification["deleted"]["row_heights"]:
|
1992
|
+
event_data["treeview"] = modification["treeview"]
|
1894
1993
|
self.add_rows(
|
1895
1994
|
rows=modification["deleted"]["rows"],
|
1896
1995
|
index=modification["deleted"]["index"],
|
1897
1996
|
row_heights=modification["deleted"]["row_heights"],
|
1898
1997
|
event_data=event_data,
|
1899
|
-
displayed_rows=modification["deleted"]["displayed_rows"],
|
1900
1998
|
create_ops=False,
|
1901
|
-
create_selections=
|
1999
|
+
create_selections=False,
|
1902
2000
|
add_col_positions=False,
|
2001
|
+
restored_state=True,
|
1903
2002
|
)
|
1904
|
-
self.restore_options_named_spans(modification)
|
1905
2003
|
|
1906
2004
|
if modification["deleted"]["columns"] or modification["deleted"]["column_widths"]:
|
1907
2005
|
self.add_columns(
|
@@ -1909,12 +2007,11 @@ class MainTable(tk.Canvas):
|
|
1909
2007
|
header=modification["deleted"]["header"],
|
1910
2008
|
column_widths=modification["deleted"]["column_widths"],
|
1911
2009
|
event_data=event_data,
|
1912
|
-
displayed_columns=modification["deleted"]["displayed_columns"],
|
1913
2010
|
create_ops=False,
|
1914
|
-
create_selections=
|
2011
|
+
create_selections=False,
|
1915
2012
|
add_row_positions=False,
|
2013
|
+
restored_state=True,
|
1916
2014
|
)
|
1917
|
-
self.restore_options_named_spans(modification)
|
1918
2015
|
|
1919
2016
|
if modification["eventname"].startswith(("edit", "move")):
|
1920
2017
|
if not saved_cells:
|
@@ -1927,6 +2024,8 @@ class MainTable(tk.Canvas):
|
|
1927
2024
|
elif modification["eventname"].startswith("delete"):
|
1928
2025
|
event_data["eventname"] = modification["eventname"].replace("delete", "add")
|
1929
2026
|
|
2027
|
+
self.restore_sheet_state(modification)
|
2028
|
+
|
1930
2029
|
if not modification["eventname"].startswith("move") and (
|
1931
2030
|
len(self.row_positions) > 1 or len(self.col_positions) > 1
|
1932
2031
|
):
|
@@ -2819,7 +2918,7 @@ class MainTable(tk.Canvas):
|
|
2819
2918
|
self.menu_add_command(
|
2820
2919
|
self.CH.ch_rc_popup_menu,
|
2821
2920
|
label=self.PAR.ops.delete_columns_label,
|
2822
|
-
command=self.
|
2921
|
+
command=self.delete_columns,
|
2823
2922
|
**mnkwgs,
|
2824
2923
|
)
|
2825
2924
|
if self.rc_insert_column_enabled:
|
@@ -2845,7 +2944,7 @@ class MainTable(tk.Canvas):
|
|
2845
2944
|
self.menu_add_command(
|
2846
2945
|
self.RI.ri_rc_popup_menu,
|
2847
2946
|
label=self.PAR.ops.delete_rows_label,
|
2848
|
-
command=self.
|
2947
|
+
command=self.delete_rows,
|
2849
2948
|
**mnkwgs,
|
2850
2949
|
)
|
2851
2950
|
if self.rc_insert_row_enabled:
|
@@ -2867,6 +2966,99 @@ class MainTable(tk.Canvas):
|
|
2867
2966
|
command=lambda: self.rc_add_rows("below"),
|
2868
2967
|
**mnkwgs,
|
2869
2968
|
)
|
2969
|
+
if self.rc_sort_cells_enabled:
|
2970
|
+
self.menu_add_command(
|
2971
|
+
self.rc_popup_menu,
|
2972
|
+
label=self.PAR.ops.sort_cells_label,
|
2973
|
+
accelerator=self.PAR.ops.sort_cells_accelerator,
|
2974
|
+
command=self.sort_boxes,
|
2975
|
+
**mnkwgs,
|
2976
|
+
)
|
2977
|
+
self.menu_add_command(
|
2978
|
+
self.rc_popup_menu,
|
2979
|
+
label=self.PAR.ops.sort_cells_reverse_label,
|
2980
|
+
accelerator=self.PAR.ops.sort_cells_reverse_accelerator,
|
2981
|
+
command=lambda: self.sort_boxes(reverse=True),
|
2982
|
+
**mnkwgs,
|
2983
|
+
)
|
2984
|
+
self.menu_add_command(
|
2985
|
+
self.rc_popup_menu,
|
2986
|
+
label=self.PAR.ops.sort_cells_x_label,
|
2987
|
+
accelerator=self.PAR.ops.sort_cells_x_accelerator,
|
2988
|
+
command=lambda: self.sort_boxes(row_wise=True),
|
2989
|
+
**mnkwgs,
|
2990
|
+
)
|
2991
|
+
self.menu_add_command(
|
2992
|
+
self.rc_popup_menu,
|
2993
|
+
label=self.PAR.ops.sort_cells_x_reverse_label,
|
2994
|
+
accelerator=self.PAR.ops.sort_cells_x_reverse_accelerator,
|
2995
|
+
command=lambda: self.sort_boxes(reverse=True, row_wise=True),
|
2996
|
+
**mnkwgs,
|
2997
|
+
)
|
2998
|
+
# row index sort rows cells
|
2999
|
+
if self.rc_sort_row_enabled:
|
3000
|
+
self.menu_add_command(
|
3001
|
+
self.RI.ri_rc_popup_menu,
|
3002
|
+
label=self.PAR.ops.sort_row_label,
|
3003
|
+
accelerator=self.PAR.ops.sort_row_accelerator,
|
3004
|
+
command=self.RI._sort_rows,
|
3005
|
+
**mnkwgs,
|
3006
|
+
)
|
3007
|
+
self.menu_add_command(
|
3008
|
+
self.RI.ri_rc_popup_menu,
|
3009
|
+
label=self.PAR.ops.sort_row_reverse_label,
|
3010
|
+
accelerator=self.PAR.ops.sort_row_reverse_accelerator,
|
3011
|
+
command=lambda: self.RI._sort_rows(reverse=True),
|
3012
|
+
**mnkwgs,
|
3013
|
+
)
|
3014
|
+
# header sort columns cells
|
3015
|
+
if self.rc_sort_column_enabled:
|
3016
|
+
self.menu_add_command(
|
3017
|
+
self.CH.ch_rc_popup_menu,
|
3018
|
+
label=self.PAR.ops.sort_column_label,
|
3019
|
+
accelerator=self.PAR.ops.sort_column_accelerator,
|
3020
|
+
command=self.CH._sort_columns,
|
3021
|
+
**mnkwgs,
|
3022
|
+
)
|
3023
|
+
self.menu_add_command(
|
3024
|
+
self.CH.ch_rc_popup_menu,
|
3025
|
+
label=self.PAR.ops.sort_column_reverse_label,
|
3026
|
+
accelerator=self.PAR.ops.sort_column_reverse_accelerator,
|
3027
|
+
command=lambda: self.CH._sort_columns(reverse=True),
|
3028
|
+
**mnkwgs,
|
3029
|
+
)
|
3030
|
+
# row index sort columns by row
|
3031
|
+
if self.rc_sort_columns_enabled:
|
3032
|
+
self.menu_add_command(
|
3033
|
+
self.RI.ri_rc_popup_menu,
|
3034
|
+
label=self.PAR.ops.sort_columns_label,
|
3035
|
+
accelerator=self.PAR.ops.sort_columns_accelerator,
|
3036
|
+
command=self.RI._sort_columns_by_row,
|
3037
|
+
**mnkwgs,
|
3038
|
+
)
|
3039
|
+
self.menu_add_command(
|
3040
|
+
self.RI.ri_rc_popup_menu,
|
3041
|
+
label=self.PAR.ops.sort_columns_reverse_label,
|
3042
|
+
accelerator=self.PAR.ops.sort_columns_reverse_accelerator,
|
3043
|
+
command=lambda: self.RI._sort_columns_by_row(reverse=True),
|
3044
|
+
**mnkwgs,
|
3045
|
+
)
|
3046
|
+
# header sort rows by column
|
3047
|
+
if self.rc_sort_rows_enabled:
|
3048
|
+
self.menu_add_command(
|
3049
|
+
self.CH.ch_rc_popup_menu,
|
3050
|
+
label=self.PAR.ops.sort_rows_label,
|
3051
|
+
accelerator=self.PAR.ops.sort_rows_accelerator,
|
3052
|
+
command=self.CH._sort_rows_by_column,
|
3053
|
+
**mnkwgs,
|
3054
|
+
)
|
3055
|
+
self.menu_add_command(
|
3056
|
+
self.CH.ch_rc_popup_menu,
|
3057
|
+
label=self.PAR.ops.sort_rows_reverse_label,
|
3058
|
+
accelerator=self.PAR.ops.sort_rows_reverse_accelerator,
|
3059
|
+
command=lambda: self.CH._sort_rows_by_column(reverse=True),
|
3060
|
+
**mnkwgs,
|
3061
|
+
)
|
2870
3062
|
for label, func in self.extra_table_rc_menu_funcs.items():
|
2871
3063
|
self.menu_add_command(
|
2872
3064
|
self.rc_popup_menu,
|
@@ -3037,6 +3229,16 @@ class MainTable(tk.Canvas):
|
|
3037
3229
|
self.rc_insert_row_enabled = True
|
3038
3230
|
self.rc_popup_menus_enabled = True
|
3039
3231
|
self.rc_select_enabled = True
|
3232
|
+
if binding in ("all", "sort_cells"):
|
3233
|
+
self.rc_sort_cells_enabled = True
|
3234
|
+
if binding in ("all", "sort_row"):
|
3235
|
+
self.rc_sort_row_enabled = True
|
3236
|
+
if binding in ("all", "sort_column", "sort_col"):
|
3237
|
+
self.rc_sort_column_enabled = True
|
3238
|
+
if binding in ("all", "sort_columns", "sort_cols"):
|
3239
|
+
self.rc_sort_columns_enabled = True
|
3240
|
+
if binding in ("all", "sort_rows"):
|
3241
|
+
self.rc_sort_rows_enabled = True
|
3040
3242
|
if binding in ("all", "right_click_popup_menu", "rc_popup_menu", "rc_menu"):
|
3041
3243
|
self.rc_popup_menus_enabled = True
|
3042
3244
|
self.rc_select_enabled = True
|
@@ -3110,6 +3312,16 @@ class MainTable(tk.Canvas):
|
|
3110
3312
|
self.rc_insert_column_enabled = False
|
3111
3313
|
if binding in bind_add_rows:
|
3112
3314
|
self.rc_insert_row_enabled = False
|
3315
|
+
if binding in ("all", "sort_cells"):
|
3316
|
+
self.rc_sort_cells_enabled = False
|
3317
|
+
if binding in ("all", "sort_row"):
|
3318
|
+
self.rc_sort_row_enabled = False
|
3319
|
+
if binding in ("all", "sort_column", "sort_col"):
|
3320
|
+
self.rc_sort_column_enabled = False
|
3321
|
+
if binding in ("all", "sort_columns", "sort_cols"):
|
3322
|
+
self.rc_sort_columns_enabled = False
|
3323
|
+
if binding in ("all", "sort_rows"):
|
3324
|
+
self.rc_sort_rows_enabled = False
|
3113
3325
|
if binding in ("all", "right_click_popup_menu", "rc_popup_menu", "rc_menu"):
|
3114
3326
|
self.rc_popup_menus_enabled = False
|
3115
3327
|
if binding in ("all", "right_click_select", "rc_select"):
|
@@ -3255,12 +3467,12 @@ class MainTable(tk.Canvas):
|
|
3255
3467
|
t, sh = self.hidd_resize_lines.popitem()
|
3256
3468
|
self.coords(t, x1, y1, x2, y2)
|
3257
3469
|
if sh:
|
3258
|
-
self.itemconfig(t, width=width, fill=fill,
|
3470
|
+
self.itemconfig(t, width=width, fill=fill, tags=tag)
|
3259
3471
|
else:
|
3260
|
-
self.itemconfig(t, width=width, fill=fill,
|
3472
|
+
self.itemconfig(t, width=width, fill=fill, tags=tag, state="normal")
|
3261
3473
|
self.lift(t)
|
3262
3474
|
else:
|
3263
|
-
t = self.create_line(x1, y1, x2, y2, width=width, fill=fill,
|
3475
|
+
t = self.create_line(x1, y1, x2, y2, width=width, fill=fill, tags=tag)
|
3264
3476
|
self.disp_resize_lines[t] = True
|
3265
3477
|
|
3266
3478
|
def delete_resize_lines(self):
|
@@ -3768,38 +3980,14 @@ class MainTable(tk.Canvas):
|
|
3768
3980
|
c_pc = 0.0
|
3769
3981
|
old_min_row_height = int(self.min_row_height)
|
3770
3982
|
old_default_row_height = int(self.get_default_row_height())
|
3771
|
-
self.set_table_font(
|
3772
|
-
|
3773
|
-
reset_row_positions=False,
|
3774
|
-
)
|
3775
|
-
self.set_index_font(index_font)
|
3983
|
+
self.set_table_font(table_font, row_heights=False)
|
3984
|
+
self.set_index_font(index_font, row_heights=False)
|
3776
3985
|
self.set_header_font(header_font)
|
3777
3986
|
if self.PAR.ops.set_cell_sizes_on_zoom:
|
3778
3987
|
self.set_all_cell_sizes_to_text()
|
3779
3988
|
self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
3780
3989
|
elif not self.PAR.ops.set_cell_sizes_on_zoom:
|
3781
|
-
|
3782
|
-
self.row_positions = list(
|
3783
|
-
accumulate(
|
3784
|
-
chain(
|
3785
|
-
[0],
|
3786
|
-
(
|
3787
|
-
(
|
3788
|
-
self.min_row_height
|
3789
|
-
if h == old_min_row_height
|
3790
|
-
else (
|
3791
|
-
default_row_height
|
3792
|
-
if h == old_default_row_height
|
3793
|
-
else self.min_row_height
|
3794
|
-
if h < self.min_row_height
|
3795
|
-
else h
|
3796
|
-
)
|
3797
|
-
)
|
3798
|
-
for h in self.gen_row_heights()
|
3799
|
-
),
|
3800
|
-
)
|
3801
|
-
)
|
3802
|
-
)
|
3990
|
+
self.change_font_manage_row_heights(old_min_row_height, old_default_row_height)
|
3803
3991
|
self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
3804
3992
|
self.recreate_all_selection_boxes()
|
3805
3993
|
self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
@@ -3843,13 +4031,20 @@ class MainTable(tk.Canvas):
|
|
3843
4031
|
return b[2] - b[0], b[3] - b[1]
|
3844
4032
|
|
3845
4033
|
def get_lines_cell_height(self, n: int, font: None | FontTuple = None) -> int:
|
3846
|
-
|
3847
|
-
self.
|
4034
|
+
if font == self.PAR.ops.table_font:
|
4035
|
+
return 3 + (n * self.table_txt_height)
|
4036
|
+
|
4037
|
+
elif font == self.PAR.ops.index_font:
|
4038
|
+
return 3 + (n * self.index_txt_height)
|
4039
|
+
|
4040
|
+
elif font == self.PAR.ops.header_font:
|
4041
|
+
return 3 + (n * self.header_txt_height)
|
4042
|
+
|
4043
|
+
else:
|
4044
|
+
return 3 + self.get_txt_h(
|
3848
4045
|
txt="\n".join("|" for _ in range(n)) if n > 1 else "|",
|
3849
|
-
font=
|
4046
|
+
font=font,
|
3850
4047
|
)
|
3851
|
-
+ 5
|
3852
|
-
)
|
3853
4048
|
|
3854
4049
|
def set_min_column_width(self, width: int) -> None:
|
3855
4050
|
if width:
|
@@ -3880,62 +4075,95 @@ class MainTable(tk.Canvas):
|
|
3880
4075
|
)
|
3881
4076
|
return self.PAR.ops.default_header_height
|
3882
4077
|
|
3883
|
-
def
|
4078
|
+
def check_font(self, newfont: tuple) -> None:
|
4079
|
+
if (
|
4080
|
+
not isinstance(newfont, tuple)
|
4081
|
+
or len(newfont) != 3
|
4082
|
+
or not isinstance(newfont[0], str)
|
4083
|
+
or not isinstance(newfont[1], int)
|
4084
|
+
or not isinstance(newfont[2], str)
|
4085
|
+
):
|
4086
|
+
raise ValueError(font_value_error)
|
4087
|
+
|
4088
|
+
def set_table_font(self, newfont: tuple | None = None, row_heights: bool = True) -> tuple[str, int, str]:
|
3884
4089
|
if newfont:
|
3885
|
-
|
3886
|
-
raise ValueError("Argument must be tuple e.g. ('Carlito', 12, 'normal')")
|
3887
|
-
if len(newfont) != 3:
|
3888
|
-
raise ValueError("Argument must be three-tuple")
|
3889
|
-
if not isinstance(newfont[0], str) or not isinstance(newfont[1], int) or not isinstance(newfont[2], str):
|
3890
|
-
raise ValueError(
|
3891
|
-
"Argument must be font, size and 'normal', 'bold' or'italic' e.g. ('Carlito',12,'normal')"
|
3892
|
-
)
|
4090
|
+
self.check_font(newfont)
|
3893
4091
|
self.PAR.ops.table_font = FontTuple(*newfont)
|
4092
|
+
old_min_row_height = int(self.min_row_height)
|
4093
|
+
old_default_row_height = int(self.get_default_row_height())
|
3894
4094
|
self.set_table_font_help()
|
3895
|
-
if
|
3896
|
-
|
3897
|
-
self.reset_row_positions()
|
3898
|
-
else:
|
3899
|
-
self.set_row_positions(itr=reset_row_positions)
|
4095
|
+
if row_heights:
|
4096
|
+
self.change_font_manage_row_heights(old_min_row_height, old_default_row_height)
|
3900
4097
|
self.recreate_all_selection_boxes()
|
3901
4098
|
return self.PAR.ops.table_font
|
3902
4099
|
|
3903
4100
|
def set_table_font_help(self):
|
4101
|
+
self.table_font = self.PAR.ops.table_font
|
4102
|
+
if self.PAR.ops.table_font not in self.char_widths:
|
4103
|
+
self.char_widths[self.PAR.ops.table_font] = {}
|
4104
|
+
self.table_test_str_w = self.get_txt_w(_test_str)
|
3904
4105
|
self.table_txt_width, self.table_txt_height = self.get_txt_dimensions("|", self.PAR.ops.table_font)
|
3905
|
-
self.
|
3906
|
-
if not self.table_half_txt_height % 2:
|
3907
|
-
self.table_first_ln_ins = self.table_half_txt_height + 2
|
3908
|
-
else:
|
3909
|
-
self.table_first_ln_ins = self.table_half_txt_height + 3
|
3910
|
-
self.min_row_height = int(self.table_first_ln_ins * 2.22)
|
3911
|
-
self.table_xtra_lines_increment = int(self.table_txt_height)
|
3912
|
-
if self.min_row_height < 12:
|
3913
|
-
self.min_row_height = 12
|
4106
|
+
self.min_row_height = max(6, self.table_txt_height, self.index_txt_height) + 6
|
3914
4107
|
|
3915
|
-
def
|
4108
|
+
def set_index_font(self, newfont: tuple | None = None, row_heights: bool = True) -> tuple[str, int, str]:
|
3916
4109
|
if newfont:
|
3917
|
-
|
3918
|
-
|
3919
|
-
|
3920
|
-
|
3921
|
-
|
3922
|
-
|
3923
|
-
|
4110
|
+
self.check_font(newfont)
|
4111
|
+
self.PAR.ops.index_font = FontTuple(*newfont)
|
4112
|
+
old_min_row_height = int(self.min_row_height)
|
4113
|
+
old_default_row_height = int(self.get_default_row_height())
|
4114
|
+
self.set_index_font_help()
|
4115
|
+
if row_heights:
|
4116
|
+
self.change_font_manage_row_heights(old_min_row_height, old_default_row_height)
|
4117
|
+
self.recreate_all_selection_boxes()
|
4118
|
+
return self.PAR.ops.index_font
|
4119
|
+
|
4120
|
+
def set_index_font_help(self):
|
4121
|
+
self.RI.index_font = self.PAR.ops.index_font
|
4122
|
+
if self.PAR.ops.index_font not in self.char_widths:
|
4123
|
+
self.char_widths[self.PAR.ops.index_font] = {}
|
4124
|
+
self.RI.index_test_str_w = self.get_txt_w(_test_str, self.PAR.ops.index_font)
|
4125
|
+
self.index_txt_width, self.index_txt_height = self.get_txt_dimensions("|", self.PAR.ops.index_font)
|
4126
|
+
self.min_row_height = max(6, self.table_txt_height, self.index_txt_height) + 6
|
4127
|
+
|
4128
|
+
def change_font_manage_row_heights(self, old_min_row_height: int, old_default_row_height: int) -> None:
|
4129
|
+
default_row_height = self.get_default_row_height()
|
4130
|
+
self.row_positions = list(
|
4131
|
+
accumulate(
|
4132
|
+
chain(
|
4133
|
+
[0],
|
4134
|
+
(
|
4135
|
+
(
|
4136
|
+
self.min_row_height
|
4137
|
+
if h == old_min_row_height
|
4138
|
+
else (
|
4139
|
+
default_row_height
|
4140
|
+
if h == old_default_row_height
|
4141
|
+
else self.min_row_height
|
4142
|
+
if h < self.min_row_height
|
4143
|
+
else h
|
4144
|
+
)
|
4145
|
+
)
|
4146
|
+
for h in self.gen_row_heights()
|
4147
|
+
),
|
3924
4148
|
)
|
4149
|
+
)
|
4150
|
+
)
|
4151
|
+
|
4152
|
+
def set_header_font(self, newfont: tuple | None = None) -> tuple[str, int, str]:
|
4153
|
+
if newfont:
|
4154
|
+
self.check_font(newfont)
|
3925
4155
|
self.PAR.ops.header_font = FontTuple(*newfont)
|
3926
4156
|
self.set_header_font_help()
|
3927
4157
|
self.recreate_all_selection_boxes()
|
3928
4158
|
return self.PAR.ops.header_font
|
3929
4159
|
|
3930
4160
|
def set_header_font_help(self):
|
4161
|
+
self.CH.header_font = self.PAR.ops.header_font
|
4162
|
+
if self.PAR.ops.header_font not in self.char_widths:
|
4163
|
+
self.char_widths[self.PAR.ops.header_font] = {}
|
4164
|
+
self.CH.header_test_str_w = self.get_txt_w(_test_str, self.PAR.ops.header_font)
|
3931
4165
|
self.header_txt_width, self.header_txt_height = self.get_txt_dimensions("|", self.PAR.ops.header_font)
|
3932
|
-
self.
|
3933
|
-
if not self.header_half_txt_height % 2:
|
3934
|
-
self.header_first_ln_ins = self.header_half_txt_height + 2
|
3935
|
-
else:
|
3936
|
-
self.header_first_ln_ins = self.header_half_txt_height + 3
|
3937
|
-
self.header_xtra_lines_increment = self.header_txt_height
|
3938
|
-
self.min_header_height = int(self.header_first_ln_ins * 2.22)
|
4166
|
+
self.min_header_height = self.header_txt_height + 6
|
3939
4167
|
if (
|
3940
4168
|
isinstance(self.PAR.ops.default_header_height, int)
|
3941
4169
|
and self.PAR.ops.default_header_height < self.min_header_height
|
@@ -3943,30 +4171,6 @@ class MainTable(tk.Canvas):
|
|
3943
4171
|
self.PAR.ops.default_header_height = int(self.min_header_height)
|
3944
4172
|
self.CH.set_height(self.get_default_header_height(), set_TL=True)
|
3945
4173
|
|
3946
|
-
def set_index_font(self, newfont: tuple | None = None) -> tuple[str, int, str]:
|
3947
|
-
if newfont:
|
3948
|
-
if not isinstance(newfont, tuple):
|
3949
|
-
raise ValueError("Argument must be tuple e.g. ('Carlito', 12, 'normal')")
|
3950
|
-
if len(newfont) != 3:
|
3951
|
-
raise ValueError("Argument must be three-tuple")
|
3952
|
-
if not isinstance(newfont[0], str) or not isinstance(newfont[1], int) or not isinstance(newfont[2], str):
|
3953
|
-
raise ValueError(
|
3954
|
-
"Argument must be font, size and 'normal', 'bold' or'italic' e.g. ('Carlito',12,'normal')"
|
3955
|
-
)
|
3956
|
-
self.PAR.ops.index_font = FontTuple(*newfont)
|
3957
|
-
self.set_index_font_help()
|
3958
|
-
return self.PAR.ops.index_font
|
3959
|
-
|
3960
|
-
def set_index_font_help(self):
|
3961
|
-
self.index_txt_width, self.index_txt_height = self.get_txt_dimensions("|", self.PAR.ops.index_font)
|
3962
|
-
self.index_half_txt_height = ceil(self.index_txt_height / 2)
|
3963
|
-
if not self.index_half_txt_height % 2:
|
3964
|
-
self.index_first_ln_ins = self.index_half_txt_height + 2
|
3965
|
-
else:
|
3966
|
-
self.index_first_ln_ins = self.index_half_txt_height + 3
|
3967
|
-
self.index_xtra_lines_increment = self.index_txt_height
|
3968
|
-
self.min_index_width = 5
|
3969
|
-
|
3970
4174
|
def purge_undo_and_redo_stack(self):
|
3971
4175
|
self.undo_stack = deque(maxlen=self.PAR.ops.max_undos)
|
3972
4176
|
self.redo_stack = deque(maxlen=self.PAR.ops.max_undos)
|
@@ -4088,6 +4292,58 @@ class MainTable(tk.Canvas):
|
|
4088
4292
|
else:
|
4089
4293
|
return False
|
4090
4294
|
|
4295
|
+
def get_cell_max_width(self, datarn: int, dispcn: int) -> int:
|
4296
|
+
datacn = self.datacn(dispcn)
|
4297
|
+
col_width = self.col_positions[dispcn + 1] - self.col_positions[dispcn]
|
4298
|
+
if kwargs := self.get_cell_kwargs(datarn, datacn, "dropdown"):
|
4299
|
+
max_width = col_width - self.table_txt_height - 5
|
4300
|
+
else:
|
4301
|
+
max_width = col_width - 2
|
4302
|
+
if (kwargs := self.get_cell_kwargs(datarn, datacn, "dropdown")) and max_width > self.table_txt_height + 1:
|
4303
|
+
box_w = self.table_txt_height + 1
|
4304
|
+
max_width -= box_w + 4
|
4305
|
+
if self.PAR.ops.allow_cell_overflow and not kwargs:
|
4306
|
+
if self.cells_cache is None:
|
4307
|
+
disprn = self.disprn(datarn)
|
4308
|
+
self.cells_cache = self._redraw_precache_cells(disprn, disprn + 1, 0, len(self.col_positions) - 1)
|
4309
|
+
if not (align := self.get_cell_kwargs(datarn, datacn, key="align")):
|
4310
|
+
align = self.align
|
4311
|
+
if align.endswith("w"):
|
4312
|
+
max_width += sum(
|
4313
|
+
self._overflow(
|
4314
|
+
self.cells_cache,
|
4315
|
+
range(dispcn + 1, len(self.col_positions) - 1),
|
4316
|
+
datarn,
|
4317
|
+
)
|
4318
|
+
)
|
4319
|
+
elif align.endswith("e"):
|
4320
|
+
max_width += sum(
|
4321
|
+
self._overflow(
|
4322
|
+
self.cells_cache,
|
4323
|
+
reversed(range(0, dispcn)),
|
4324
|
+
datarn,
|
4325
|
+
)
|
4326
|
+
)
|
4327
|
+
return max_width
|
4328
|
+
|
4329
|
+
def get_wrapped_cell_height(self, datarn: int, datacn: int) -> int:
|
4330
|
+
dispcn = self.dispcn(datacn)
|
4331
|
+
n_lines = max(
|
4332
|
+
1,
|
4333
|
+
sum(
|
4334
|
+
1
|
4335
|
+
for _ in wrap_text(
|
4336
|
+
text=self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True),
|
4337
|
+
max_width=self.get_cell_max_width(datarn, dispcn),
|
4338
|
+
max_lines=float("inf"),
|
4339
|
+
char_width_fn=self.wrap_get_char_w,
|
4340
|
+
widths=self.char_widths[self.table_font],
|
4341
|
+
wrap=self.PAR.ops.table_wrap,
|
4342
|
+
)
|
4343
|
+
),
|
4344
|
+
)
|
4345
|
+
return 3 + (n_lines * self.table_txt_height)
|
4346
|
+
|
4091
4347
|
def set_all_cell_sizes_to_text(
|
4092
4348
|
self,
|
4093
4349
|
width: int | None = None,
|
@@ -4171,26 +4427,28 @@ class MainTable(tk.Canvas):
|
|
4171
4427
|
def set_col_positions(self, itr: AnyIter[float]) -> None:
|
4172
4428
|
self.col_positions = list(accumulate(chain([0], itr)))
|
4173
4429
|
|
4174
|
-
def reset_col_positions(self, ncols: int | None = None):
|
4175
|
-
|
4430
|
+
def reset_col_positions(self, ncols: int | None = None, width: int | None = None) -> None:
|
4431
|
+
if width is None:
|
4432
|
+
width = self.PAR.ops.default_column_width
|
4176
4433
|
if isinstance(ncols, int):
|
4177
|
-
self.set_col_positions(itr=repeat(
|
4434
|
+
self.set_col_positions(itr=repeat(width, ncols))
|
4178
4435
|
elif self.all_columns_displayed:
|
4179
|
-
self.set_col_positions(itr=repeat(
|
4436
|
+
self.set_col_positions(itr=repeat(width, self.total_data_cols()))
|
4180
4437
|
else:
|
4181
|
-
self.set_col_positions(itr=repeat(
|
4438
|
+
self.set_col_positions(itr=repeat(width, len(self.displayed_columns)))
|
4182
4439
|
|
4183
4440
|
def set_row_positions(self, itr: AnyIter[float]) -> None:
|
4184
4441
|
self.row_positions = list(accumulate(chain([0], itr)))
|
4185
4442
|
|
4186
|
-
def reset_row_positions(self, nrows: int | None = None):
|
4187
|
-
|
4443
|
+
def reset_row_positions(self, nrows: int | None = None, height: int | None = None) -> None:
|
4444
|
+
if height is None:
|
4445
|
+
height = self.get_default_row_height()
|
4188
4446
|
if isinstance(nrows, int):
|
4189
|
-
self.set_row_positions(itr=repeat(
|
4447
|
+
self.set_row_positions(itr=repeat(height, nrows))
|
4190
4448
|
elif self.all_rows_displayed:
|
4191
|
-
self.set_row_positions(itr=repeat(
|
4449
|
+
self.set_row_positions(itr=repeat(height, self.total_data_rows()))
|
4192
4450
|
else:
|
4193
|
-
self.set_row_positions(itr=repeat(
|
4451
|
+
self.set_row_positions(itr=repeat(height, len(self.displayed_rows)))
|
4194
4452
|
|
4195
4453
|
def del_col_position(self, idx: int, deselect_all: bool = False):
|
4196
4454
|
if deselect_all:
|
@@ -4242,46 +4500,6 @@ class MainTable(tk.Canvas):
|
|
4242
4500
|
def gen_row_heights(self) -> Generator[int]:
|
4243
4501
|
return diff_gen(self.row_positions)
|
4244
4502
|
|
4245
|
-
def insert_col_position(
|
4246
|
-
self,
|
4247
|
-
idx: Literal["end"] | int = "end",
|
4248
|
-
width: int | None = None,
|
4249
|
-
deselect_all: bool = False,
|
4250
|
-
) -> None:
|
4251
|
-
if deselect_all:
|
4252
|
-
self.deselect("all", redraw=False)
|
4253
|
-
if width is None:
|
4254
|
-
w = self.PAR.ops.default_column_width
|
4255
|
-
else:
|
4256
|
-
w = width
|
4257
|
-
if idx == "end" or len(self.col_positions) == idx + 1:
|
4258
|
-
self.col_positions.append(self.col_positions[-1] + w)
|
4259
|
-
else:
|
4260
|
-
idx += 1
|
4261
|
-
self.col_positions.insert(idx, self.col_positions[idx - 1] + w)
|
4262
|
-
idx += 1
|
4263
|
-
self.col_positions[idx:] = [e + w for e in islice(self.col_positions, idx, len(self.col_positions))]
|
4264
|
-
|
4265
|
-
def insert_row_position(
|
4266
|
-
self,
|
4267
|
-
idx: Literal["end"] | int = "end",
|
4268
|
-
height: int | None = None,
|
4269
|
-
deselect_all: bool = False,
|
4270
|
-
) -> None:
|
4271
|
-
if deselect_all:
|
4272
|
-
self.deselect("all", redraw=False)
|
4273
|
-
if height is None:
|
4274
|
-
h = self.get_default_row_height()
|
4275
|
-
else:
|
4276
|
-
h = height
|
4277
|
-
if idx == "end" or len(self.row_positions) == idx + 1:
|
4278
|
-
self.row_positions.append(self.row_positions[-1] + h)
|
4279
|
-
else:
|
4280
|
-
idx += 1
|
4281
|
-
self.row_positions.insert(idx, self.row_positions[idx - 1] + h)
|
4282
|
-
idx += 1
|
4283
|
-
self.row_positions[idx:] = [e + h for e in islice(self.row_positions, idx, len(self.row_positions))]
|
4284
|
-
|
4285
4503
|
def insert_col_positions(
|
4286
4504
|
self,
|
4287
4505
|
idx: Literal["end"] | int = "end",
|
@@ -4368,25 +4586,13 @@ class MainTable(tk.Canvas):
|
|
4368
4586
|
create_ops: bool = True,
|
4369
4587
|
) -> None:
|
4370
4588
|
self.tagged_cells = {
|
4371
|
-
tags: {(r, c
|
4372
|
-
for tags, tagged in self.tagged_cells.items()
|
4373
|
-
}
|
4374
|
-
self.cell_options = {
|
4375
|
-
(r, c if not (num := bisect_right(cols, c)) else c + num): v for (r, c), v in self.cell_options.items()
|
4376
|
-
}
|
4377
|
-
self.progress_bars = {
|
4378
|
-
(r, c if not (num := bisect_right(cols, c)) else c + num): v for (r, c), v in self.progress_bars.items()
|
4379
|
-
}
|
4380
|
-
self.tagged_columns = {
|
4381
|
-
tags: {c if not (num := bisect_right(cols, c)) else c + num for c in tagged}
|
4382
|
-
for tags, tagged in self.tagged_columns.items()
|
4383
|
-
}
|
4384
|
-
self.col_options = {
|
4385
|
-
c if not (num := bisect_right(cols, c)) else c + num: v for c, v in self.col_options.items()
|
4386
|
-
}
|
4387
|
-
self.CH.cell_options = {
|
4388
|
-
c if not (num := bisect_right(cols, c)) else c + num: v for c, v in self.CH.cell_options.items()
|
4589
|
+
tags: {(r, push_n(c, cols)) for (r, c) in tagged} for tags, tagged in self.tagged_cells.items()
|
4389
4590
|
}
|
4591
|
+
self.cell_options = {(r, push_n(c, cols)): v for (r, c), v in self.cell_options.items()}
|
4592
|
+
self.progress_bars = {(r, push_n(c, cols)): v for (r, c), v in self.progress_bars.items()}
|
4593
|
+
self.tagged_columns = {tags: {push_n(c, cols) for c in tagged} for tags, tagged in self.tagged_columns.items()}
|
4594
|
+
self.col_options = {push_n(c, cols): v for c, v in self.col_options.items()}
|
4595
|
+
self.CH.cell_options = {push_n(c, cols): v for c, v in self.CH.cell_options.items()}
|
4390
4596
|
# if there are named spans where columns were added
|
4391
4597
|
# add options to gap which was created by adding columns
|
4392
4598
|
totalrows = None
|
@@ -4436,32 +4642,18 @@ class MainTable(tk.Canvas):
|
|
4436
4642
|
|
4437
4643
|
def adjust_options_post_add_rows(
|
4438
4644
|
self,
|
4439
|
-
rows: list | tuple,
|
4645
|
+
rows: list[int] | tuple[int],
|
4440
4646
|
create_ops: bool = True,
|
4441
4647
|
) -> None:
|
4442
4648
|
self.tagged_cells = {
|
4443
|
-
tags: {(r
|
4444
|
-
for tags, tagged in self.tagged_cells.items()
|
4445
|
-
}
|
4446
|
-
self.cell_options = {
|
4447
|
-
(r if not (num := bisect_right(rows, r)) else r + num, c): v for (r, c), v in self.cell_options.items()
|
4448
|
-
}
|
4449
|
-
self.progress_bars = {
|
4450
|
-
(r if not (num := bisect_right(rows, r)) else r + num, c): v for (r, c), v in self.progress_bars.items()
|
4451
|
-
}
|
4452
|
-
self.tagged_rows = {
|
4453
|
-
tags: {r if not (num := bisect_right(rows, r)) else r + num for r in tagged}
|
4454
|
-
for tags, tagged in self.tagged_rows.items()
|
4455
|
-
}
|
4456
|
-
self.row_options = {
|
4457
|
-
r if not (num := bisect_right(rows, r)) else r + num: v for r, v in self.row_options.items()
|
4458
|
-
}
|
4459
|
-
self.RI.cell_options = {
|
4460
|
-
r if not (num := bisect_right(rows, r)) else r + num: v for r, v in self.RI.cell_options.items()
|
4461
|
-
}
|
4462
|
-
self.RI.tree_rns = {
|
4463
|
-
v: r if not (num := bisect_right(rows, r)) else r + num for v, r in self.RI.tree_rns.items()
|
4649
|
+
tags: {(push_n(r, rows), c) for (r, c) in tagged} for tags, tagged in self.tagged_cells.items()
|
4464
4650
|
}
|
4651
|
+
self.cell_options = {(push_n(r, rows), c): v for (r, c), v in self.cell_options.items()}
|
4652
|
+
self.progress_bars = {(push_n(r, rows), c): v for (r, c), v in self.progress_bars.items()}
|
4653
|
+
self.tagged_rows = {tags: {push_n(r, rows) for r in tagged} for tags, tagged in self.tagged_rows.items()}
|
4654
|
+
self.row_options = {push_n(r, rows): v for r, v in self.row_options.items()}
|
4655
|
+
self.RI.cell_options = {push_n(r, rows): v for r, v in self.RI.cell_options.items()}
|
4656
|
+
self.RI.tree_rns = {k: push_n(r, rows) for k, r in self.RI.tree_rns.items()}
|
4465
4657
|
# if there are named spans where rows were added
|
4466
4658
|
# add options to gap which was created by adding rows
|
4467
4659
|
totalcols = None
|
@@ -4696,29 +4888,27 @@ class MainTable(tk.Canvas):
|
|
4696
4888
|
header: dict,
|
4697
4889
|
column_widths: dict,
|
4698
4890
|
event_data: dict,
|
4699
|
-
displayed_columns: None | list[int] = None,
|
4700
4891
|
create_ops: bool = True,
|
4701
4892
|
create_selections: bool = True,
|
4702
4893
|
add_row_positions: bool = True,
|
4703
4894
|
push_ops: bool = True,
|
4704
4895
|
mod_event_boxes: bool = True,
|
4896
|
+
restored_state: bool = False,
|
4705
4897
|
) -> EventDataDict:
|
4706
4898
|
self.saved_column_widths = {}
|
4707
|
-
|
4708
|
-
if isinstance(displayed_columns, list):
|
4709
|
-
self.displayed_columns = displayed_columns
|
4710
|
-
elif not self.all_columns_displayed:
|
4899
|
+
if not restored_state and not self.all_columns_displayed:
|
4711
4900
|
self.displayed_columns = add_to_displayed(self.displayed_columns, columns)
|
4712
4901
|
cws = self.get_column_widths()
|
4713
4902
|
if column_widths and next(reversed(column_widths)) > len(cws):
|
4714
4903
|
for i in reversed(range(len(cws), len(cws) + next(reversed(column_widths)) - len(cws))):
|
4715
4904
|
column_widths[i] = self.PAR.ops.default_column_width
|
4716
|
-
|
4717
|
-
|
4718
|
-
|
4719
|
-
|
4905
|
+
if not restored_state:
|
4906
|
+
self.set_col_positions(
|
4907
|
+
itr=insert_items(
|
4908
|
+
cws,
|
4909
|
+
column_widths,
|
4910
|
+
)
|
4720
4911
|
)
|
4721
|
-
)
|
4722
4912
|
# rn needed for indexing but cn insert
|
4723
4913
|
maxrn = 0
|
4724
4914
|
for cn, rowdict in reversed(columns.items()):
|
@@ -4737,14 +4927,14 @@ class MainTable(tk.Canvas):
|
|
4737
4927
|
"table": {},
|
4738
4928
|
"index": {},
|
4739
4929
|
"row_heights": {rn: default_height for rn in range(len(self.row_positions) - 1, maxrn + 1)},
|
4740
|
-
"displayed_rows": self.displayed_rows,
|
4741
4930
|
}
|
4742
|
-
|
4743
|
-
|
4744
|
-
|
4745
|
-
|
4931
|
+
if not restored_state:
|
4932
|
+
self.set_row_positions(
|
4933
|
+
itr=chain(
|
4934
|
+
self.gen_row_heights(),
|
4935
|
+
repeat(default_height, maxrn + 1 - (len(self.row_positions) - 1)),
|
4936
|
+
)
|
4746
4937
|
)
|
4747
|
-
)
|
4748
4938
|
if isinstance(self._headers, list) and header:
|
4749
4939
|
self._headers = insert_items(self._headers, header, self.CH.fix_header)
|
4750
4940
|
if push_ops:
|
@@ -4770,7 +4960,6 @@ class MainTable(tk.Canvas):
|
|
4770
4960
|
"table": columns,
|
4771
4961
|
"header": header,
|
4772
4962
|
"column_widths": column_widths,
|
4773
|
-
"displayed_columns": saved_displayed_columns,
|
4774
4963
|
}
|
4775
4964
|
return event_data
|
4776
4965
|
|
@@ -4807,17 +4996,14 @@ class MainTable(tk.Canvas):
|
|
4807
4996
|
numcols = self.PAR.ops.paste_insert_column_limit - len(self.col_positions) - 1
|
4808
4997
|
if numcols < 1:
|
4809
4998
|
return
|
4810
|
-
event_data =
|
4811
|
-
name="add_columns",
|
4812
|
-
sheet=self.PAR.name,
|
4813
|
-
widget=self,
|
4814
|
-
boxes=self.get_boxes(),
|
4815
|
-
selected=self.selected,
|
4816
|
-
)
|
4999
|
+
event_data = self.new_event_dict("add_columns", state=True)
|
4817
5000
|
if not try_binding(self.extra_begin_insert_cols_rc_func, event_data, "begin_add_columns"):
|
4818
5001
|
return
|
5002
|
+
columns, headers, widths = self.get_args_for_add_columns(data_ins_col, displayed_ins_col, numcols)
|
4819
5003
|
event_data = self.add_columns(
|
4820
|
-
|
5004
|
+
columns=columns,
|
5005
|
+
header=headers if isinstance(self._headers, list) and self._headers else {},
|
5006
|
+
column_widths=widths,
|
4821
5007
|
event_data=event_data,
|
4822
5008
|
)
|
4823
5009
|
if self.undo_enabled:
|
@@ -4828,34 +5014,33 @@ class MainTable(tk.Canvas):
|
|
4828
5014
|
|
4829
5015
|
def add_rows(
|
4830
5016
|
self,
|
4831
|
-
rows: dict,
|
4832
|
-
index: dict,
|
4833
|
-
row_heights: dict,
|
4834
|
-
event_data:
|
4835
|
-
displayed_rows: None | list[int] = None,
|
5017
|
+
rows: dict[int, list[object]],
|
5018
|
+
index: dict[int, object],
|
5019
|
+
row_heights: dict[int, float | int],
|
5020
|
+
event_data: EventDataDict,
|
4836
5021
|
create_ops: bool = True,
|
4837
5022
|
create_selections: bool = True,
|
4838
5023
|
add_col_positions: bool = True,
|
4839
5024
|
push_ops: bool = True,
|
5025
|
+
tree: bool = True,
|
4840
5026
|
mod_event_boxes: bool = True,
|
5027
|
+
restored_state: bool = False,
|
4841
5028
|
) -> EventDataDict:
|
4842
5029
|
self.saved_row_heights = {}
|
4843
|
-
|
4844
|
-
if isinstance(displayed_rows, list):
|
4845
|
-
self.displayed_rows = displayed_rows
|
4846
|
-
elif not self.all_rows_displayed:
|
5030
|
+
if not restored_state and not self.all_rows_displayed:
|
4847
5031
|
self.displayed_rows = add_to_displayed(self.displayed_rows, rows)
|
4848
5032
|
rhs = self.get_row_heights()
|
4849
5033
|
if row_heights and next(reversed(row_heights)) > len(rhs):
|
4850
5034
|
default_row_height = self.get_default_row_height()
|
4851
5035
|
for i in reversed(range(len(rhs), len(rhs) + next(reversed(row_heights)) - len(rhs))):
|
4852
5036
|
row_heights[i] = default_row_height
|
4853
|
-
|
4854
|
-
|
4855
|
-
|
4856
|
-
|
5037
|
+
if not restored_state:
|
5038
|
+
self.set_row_positions(
|
5039
|
+
itr=insert_items(
|
5040
|
+
rhs,
|
5041
|
+
row_heights,
|
5042
|
+
)
|
4857
5043
|
)
|
4858
|
-
)
|
4859
5044
|
maxcn = 0
|
4860
5045
|
# rn needed for insert but cn indexing
|
4861
5046
|
for rn, row in reversed(rows.items()):
|
@@ -4874,14 +5059,14 @@ class MainTable(tk.Canvas):
|
|
4874
5059
|
"table": {},
|
4875
5060
|
"header": {},
|
4876
5061
|
"column_widths": {cn: default_width for cn in range(len(self.col_positions) - 1, maxcn + 1)},
|
4877
|
-
"displayed_columns": self.displayed_columns,
|
4878
5062
|
}
|
4879
|
-
|
4880
|
-
|
4881
|
-
|
4882
|
-
|
5063
|
+
if not restored_state:
|
5064
|
+
self.set_col_positions(
|
5065
|
+
itr=chain(
|
5066
|
+
self.gen_column_widths(),
|
5067
|
+
repeat(default_width, maxcn + 1 - (len(self.col_positions) - 1)),
|
5068
|
+
)
|
4883
5069
|
)
|
4884
|
-
)
|
4885
5070
|
if push_ops:
|
4886
5071
|
self.adjust_options_post_add_rows(
|
4887
5072
|
rows=tuple(reversed(rows)),
|
@@ -4905,8 +5090,9 @@ class MainTable(tk.Canvas):
|
|
4905
5090
|
"table": rows,
|
4906
5091
|
"index": index,
|
4907
5092
|
"row_heights": row_heights,
|
4908
|
-
"displayed_rows": saved_displayed_rows,
|
4909
5093
|
}
|
5094
|
+
if tree and self.PAR.ops.treeview:
|
5095
|
+
event_data = self.RI.tree_add_rows(event_data=event_data)
|
4910
5096
|
return event_data
|
4911
5097
|
|
4912
5098
|
def rc_add_rows(self, event: object = None):
|
@@ -4942,17 +5128,14 @@ class MainTable(tk.Canvas):
|
|
4942
5128
|
numrows = self.PAR.ops.paste_insert_row_limit - len(self.row_positions) - 1
|
4943
5129
|
if numrows < 1:
|
4944
5130
|
return
|
4945
|
-
event_data =
|
4946
|
-
name="add_rows",
|
4947
|
-
sheet=self.PAR.name,
|
4948
|
-
widget=self,
|
4949
|
-
boxes=self.get_boxes(),
|
4950
|
-
selected=self.selected,
|
4951
|
-
)
|
5131
|
+
event_data = self.new_event_dict("add_rows", state=True)
|
4952
5132
|
if not try_binding(self.extra_begin_insert_rows_rc_func, event_data, "begin_add_rows"):
|
4953
5133
|
return
|
5134
|
+
rows, index, heights = self.get_args_for_add_rows(data_ins_row, displayed_ins_row, numrows)
|
4954
5135
|
event_data = self.add_rows(
|
4955
|
-
|
5136
|
+
rows=rows,
|
5137
|
+
index=index if isinstance(self._row_index, list) and self._row_index else {},
|
5138
|
+
row_heights=heights,
|
4956
5139
|
event_data=event_data,
|
4957
5140
|
)
|
4958
5141
|
if self.undo_enabled:
|
@@ -5029,10 +5212,14 @@ class MainTable(tk.Canvas):
|
|
5029
5212
|
for datarn, v in zip(reversed(range(data_ins_row, data_ins_row + numrows)), reversed(rows))
|
5030
5213
|
}
|
5031
5214
|
else:
|
5032
|
-
|
5033
|
-
|
5034
|
-
|
5035
|
-
|
5215
|
+
if self.PAR.ops.treeview:
|
5216
|
+
nodes = [self.RI.get_value_for_empty_cell(data_ins_row, r_ops=False) for _ in range(numrows)]
|
5217
|
+
index_data = dict(zip(reversed(range(data_ins_row, data_ins_row + numrows)), reversed(nodes)))
|
5218
|
+
else:
|
5219
|
+
index_data = {
|
5220
|
+
datarn: self.RI.get_value_for_empty_cell(datarn, r_ops=False)
|
5221
|
+
for datarn in reversed(range(data_ins_row, data_ins_row + numrows))
|
5222
|
+
}
|
5036
5223
|
if rows is None:
|
5037
5224
|
if total_data_cols is None:
|
5038
5225
|
total_data_cols = self.total_data_cols()
|
@@ -5072,11 +5259,27 @@ class MainTable(tk.Canvas):
|
|
5072
5259
|
"tagged_columns": {f"{tag}": set(s) for tag, s in self.tagged_columns.items()},
|
5073
5260
|
}
|
5074
5261
|
|
5075
|
-
def
|
5262
|
+
def copy_sheet_state(self) -> dict:
|
5263
|
+
return {
|
5264
|
+
"row_positions": list(self.row_positions),
|
5265
|
+
"col_positions": list(self.col_positions),
|
5266
|
+
"displayed_rows": int(self.displayed_rows)
|
5267
|
+
if isinstance(self.displayed_rows, int)
|
5268
|
+
else list(self.displayed_rows),
|
5269
|
+
"displayed_columns": int(self.displayed_columns)
|
5270
|
+
if isinstance(self.displayed_columns, int)
|
5271
|
+
else list(self.displayed_columns),
|
5272
|
+
"all_rows_displayed": bool(self.all_rows_displayed),
|
5273
|
+
"saved_row_heights": dict(self.saved_row_heights),
|
5274
|
+
"saved_column_widths": dict(self.saved_column_widths),
|
5275
|
+
"all_columns_displayed": bool(self.all_columns_displayed),
|
5276
|
+
"tree_open_ids": set(self.RI.tree_open_ids),
|
5277
|
+
}
|
5278
|
+
|
5279
|
+
def delete_columns_data(self, cols: list[int], event_data: EventDataDict | None = None) -> EventDataDict:
|
5076
5280
|
self.mouseclick_outside_editor_or_dropdown_all_canvases()
|
5077
|
-
|
5078
|
-
|
5079
|
-
)
|
5281
|
+
if not event_data:
|
5282
|
+
event_data = self.new_event_dict("delete_columns", state=True)
|
5080
5283
|
event_data["options"] = self.copy_options()
|
5081
5284
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
5082
5285
|
for datacn in reversed(cols):
|
@@ -5104,41 +5307,72 @@ class MainTable(tk.Canvas):
|
|
5104
5307
|
]
|
5105
5308
|
return event_data
|
5106
5309
|
|
5107
|
-
def delete_columns_displayed(
|
5310
|
+
def delete_columns_displayed(
|
5311
|
+
self,
|
5312
|
+
cols: list[int],
|
5313
|
+
event_data: EventDataDict | None = None,
|
5314
|
+
restored_state: bool = False,
|
5315
|
+
) -> EventDataDict:
|
5316
|
+
if not event_data:
|
5317
|
+
event_data = self.new_event_dict("delete_columns", state=True)
|
5108
5318
|
self.saved_column_widths = {}
|
5109
|
-
|
5110
|
-
|
5111
|
-
|
5112
|
-
|
5319
|
+
if cols:
|
5320
|
+
for c in reversed(cols):
|
5321
|
+
if len(self.col_positions) > c + 1:
|
5322
|
+
event_data["deleted"]["column_widths"][c] = self.col_positions[c + 1] - self.col_positions[c]
|
5323
|
+
if not restored_state:
|
5324
|
+
cols_set = set(cols)
|
5325
|
+
self.set_col_positions(
|
5326
|
+
itr=(width for c, width in enumerate(self.gen_column_widths()) if c not in cols_set)
|
5327
|
+
)
|
5113
5328
|
return event_data
|
5114
5329
|
|
5115
|
-
def
|
5116
|
-
|
5117
|
-
|
5330
|
+
def delete_columns(
|
5331
|
+
self,
|
5332
|
+
event: object = None,
|
5333
|
+
columns: list[int] | None = None,
|
5334
|
+
data_indexes: bool = False,
|
5335
|
+
undo: bool = True,
|
5336
|
+
emit_event: bool = True,
|
5337
|
+
ext: bool = False,
|
5338
|
+
) -> EventDataDict:
|
5339
|
+
event_data = self.new_event_dict("delete_columns", state=True)
|
5340
|
+
if not columns:
|
5341
|
+
if not (columns := sorted(self.get_selected_cols())):
|
5342
|
+
return event_data
|
5343
|
+
if not ext and not try_binding(self.extra_begin_del_cols_rc_func, event_data, "begin_delete_columns"):
|
5118
5344
|
return
|
5119
|
-
|
5120
|
-
|
5121
|
-
|
5122
|
-
|
5123
|
-
|
5124
|
-
|
5345
|
+
if self.all_columns_displayed:
|
5346
|
+
data_columns = columns
|
5347
|
+
disp_columns = columns
|
5348
|
+
else:
|
5349
|
+
if data_indexes:
|
5350
|
+
data_columns = columns
|
5351
|
+
disp_columns = data_to_displayed_idxs(data_columns, self.displayed_columns)
|
5352
|
+
else:
|
5353
|
+
data_columns = [self.displayed_columns[c] for c in columns]
|
5354
|
+
disp_columns = columns
|
5355
|
+
event_data = self.delete_columns_displayed(
|
5356
|
+
disp_columns,
|
5357
|
+
event_data,
|
5125
5358
|
)
|
5126
|
-
|
5127
|
-
|
5128
|
-
|
5129
|
-
|
5130
|
-
|
5131
|
-
if self.undo_enabled:
|
5359
|
+
event_data = self.delete_columns_data(
|
5360
|
+
data_columns,
|
5361
|
+
event_data,
|
5362
|
+
)
|
5363
|
+
if undo and self.undo_enabled:
|
5132
5364
|
self.undo_stack.append(stored_event_dict(event_data))
|
5365
|
+
if not ext:
|
5366
|
+
try_binding(self.extra_end_del_cols_rc_func, event_data, "end_delete_columns")
|
5367
|
+
if emit_event:
|
5368
|
+
self.sheet_modified(event_data)
|
5133
5369
|
self.deselect("all")
|
5134
|
-
|
5135
|
-
self.sheet_modified(event_data)
|
5370
|
+
return event_data
|
5136
5371
|
|
5137
|
-
def delete_rows_data(self, rows: list, event_data:
|
5372
|
+
def delete_rows_data(self, rows: list[int], event_data: EventDataDict | None = None) -> EventDataDict:
|
5138
5373
|
self.mouseclick_outside_editor_or_dropdown_all_canvases()
|
5139
|
-
|
5140
|
-
|
5141
|
-
)
|
5374
|
+
if not event_data:
|
5375
|
+
event_data = self.new_event_dict("delete_rows", state=True)
|
5142
5376
|
event_data["options"] = self.copy_options()
|
5143
5377
|
event_data["named_spans"] = {k: span.pickle_self() for k, span in self.named_spans.items()}
|
5144
5378
|
for datarn in reversed(rows):
|
@@ -5147,6 +5381,8 @@ class MainTable(tk.Canvas):
|
|
5147
5381
|
event_data["deleted"]["index"][datarn] = self._row_index.pop(datarn)
|
5148
5382
|
except Exception:
|
5149
5383
|
continue
|
5384
|
+
if self.PAR.ops.treeview:
|
5385
|
+
event_data = self.RI.tree_del_rows(event_data=event_data)
|
5150
5386
|
rows_set = set(rows)
|
5151
5387
|
self.adjust_options_post_delete_rows(
|
5152
5388
|
to_del=rows_set,
|
@@ -5160,35 +5396,78 @@ class MainTable(tk.Canvas):
|
|
5160
5396
|
]
|
5161
5397
|
return event_data
|
5162
5398
|
|
5163
|
-
def delete_rows_displayed(
|
5399
|
+
def delete_rows_displayed(
|
5400
|
+
self,
|
5401
|
+
rows: list[int],
|
5402
|
+
event_data: EventDataDict | None = None,
|
5403
|
+
restored_state: bool = False,
|
5404
|
+
) -> EventDataDict:
|
5405
|
+
if not event_data:
|
5406
|
+
event_data = self.new_event_dict("delete_rows", state=True)
|
5164
5407
|
self.saved_row_heights = {}
|
5165
|
-
|
5166
|
-
|
5167
|
-
|
5168
|
-
|
5408
|
+
if rows:
|
5409
|
+
for r in reversed(rows):
|
5410
|
+
if len(self.row_positions) > r + 1:
|
5411
|
+
event_data["deleted"]["row_heights"][r] = self.row_positions[r + 1] - self.row_positions[r]
|
5412
|
+
if not restored_state:
|
5413
|
+
rows_set = set(rows)
|
5414
|
+
self.set_row_positions(
|
5415
|
+
itr=(height for r, height in enumerate(self.gen_row_heights()) if r not in rows_set)
|
5416
|
+
)
|
5169
5417
|
return event_data
|
5170
5418
|
|
5171
|
-
def
|
5172
|
-
|
5173
|
-
|
5419
|
+
def delete_rows(
|
5420
|
+
self,
|
5421
|
+
event: object = None,
|
5422
|
+
rows: list[int] | None = None,
|
5423
|
+
data_indexes: bool = False,
|
5424
|
+
undo: bool = True,
|
5425
|
+
emit_event: bool = True,
|
5426
|
+
ext: bool = False,
|
5427
|
+
) -> EventDataDict:
|
5428
|
+
event_data = self.new_event_dict("delete_rows", state=True)
|
5429
|
+
if not rows:
|
5430
|
+
if not (rows := sorted(self.get_selected_rows())):
|
5431
|
+
return
|
5432
|
+
if not ext and not try_binding(self.extra_begin_del_rows_rc_func, event_data, "begin_delete_rows"):
|
5174
5433
|
return
|
5175
|
-
|
5176
|
-
|
5177
|
-
|
5178
|
-
|
5179
|
-
|
5180
|
-
|
5434
|
+
if self.all_rows_displayed:
|
5435
|
+
data_rows = rows
|
5436
|
+
disp_rows = rows
|
5437
|
+
else:
|
5438
|
+
if data_indexes:
|
5439
|
+
data_rows = rows
|
5440
|
+
disp_rows = data_to_displayed_idxs(data_rows, self.displayed_rows)
|
5441
|
+
else:
|
5442
|
+
data_rows = [self.displayed_rows[r] for r in rows]
|
5443
|
+
disp_rows = rows
|
5444
|
+
if self.PAR.ops.treeview:
|
5445
|
+
data_rows = sorted(
|
5446
|
+
chain(
|
5447
|
+
data_rows,
|
5448
|
+
(
|
5449
|
+
self.RI.tree_rns[did]
|
5450
|
+
for r in data_rows
|
5451
|
+
for did in self.RI.get_iid_descendants(self._row_index[r].iid)
|
5452
|
+
),
|
5453
|
+
)
|
5454
|
+
)
|
5455
|
+
event_data = self.delete_rows_displayed(
|
5456
|
+
disp_rows,
|
5457
|
+
event_data,
|
5181
5458
|
)
|
5182
|
-
|
5183
|
-
|
5184
|
-
|
5185
|
-
|
5186
|
-
|
5187
|
-
if self.undo_enabled:
|
5459
|
+
event_data = self.delete_rows_data(
|
5460
|
+
data_rows,
|
5461
|
+
event_data,
|
5462
|
+
)
|
5463
|
+
if undo and self.undo_enabled:
|
5188
5464
|
self.undo_stack.append(stored_event_dict(event_data))
|
5465
|
+
if not ext:
|
5466
|
+
try_binding(self.extra_end_del_rows_rc_func, event_data, "end_delete_rows")
|
5467
|
+
if emit_event:
|
5468
|
+
self.sheet_modified(event_data)
|
5189
5469
|
self.deselect("all")
|
5190
|
-
|
5191
|
-
self.sheet_modified(event_data)
|
5470
|
+
return event_data
|
5192
5471
|
|
5193
5472
|
def move_row_position(self, idx1: int, idx2: int):
|
5194
5473
|
if not len(self.row_positions) <= 2:
|
@@ -5593,9 +5872,8 @@ class MainTable(tk.Canvas):
|
|
5593
5872
|
self.itemconfig(iid, fill=fill, outline=outline)
|
5594
5873
|
else:
|
5595
5874
|
self.itemconfig(iid, fill=fill, outline=outline, state="normal")
|
5596
|
-
self.tag_raise(iid)
|
5597
5875
|
else:
|
5598
|
-
iid = self.create_rectangle(coords, fill=fill, outline=outline)
|
5876
|
+
iid = self.create_rectangle(coords, fill=fill, outline=outline, tags="h")
|
5599
5877
|
self.disp_high[iid] = True
|
5600
5878
|
return True
|
5601
5879
|
|
@@ -5621,7 +5899,6 @@ class MainTable(tk.Canvas):
|
|
5621
5899
|
joinstyle=tk.ROUND,
|
5622
5900
|
state="normal",
|
5623
5901
|
)
|
5624
|
-
self.tag_raise(iid)
|
5625
5902
|
else:
|
5626
5903
|
iid = self.create_line(
|
5627
5904
|
points,
|
@@ -5811,12 +6088,67 @@ class MainTable(tk.Canvas):
|
|
5811
6088
|
self.PAR.yscroll.grid(row=0, column=2, rowspan=3, sticky="nswe")
|
5812
6089
|
self.PAR.yscroll_showing = True
|
5813
6090
|
|
6091
|
+
def _overflow(
|
6092
|
+
self,
|
6093
|
+
cells: dict,
|
6094
|
+
rnge: Generator[int],
|
6095
|
+
datarn: int,
|
6096
|
+
) -> Generator[float]:
|
6097
|
+
for c_ in rnge:
|
6098
|
+
if (
|
6099
|
+
cells[(datarn, cells["datacn"][c_])]
|
6100
|
+
or (datarn, cells["datacn"][c_]) in cells["dropdown"]
|
6101
|
+
or (datarn, cells["datacn"][c_]) in cells["checkbox"]
|
6102
|
+
):
|
6103
|
+
return
|
6104
|
+
else:
|
6105
|
+
yield self.col_positions[c_ + 1] - self.col_positions[c_]
|
6106
|
+
|
6107
|
+
def _redraw_precache_cells(
|
6108
|
+
self,
|
6109
|
+
text_start_row: int,
|
6110
|
+
text_end_row: int,
|
6111
|
+
text_start_col: int,
|
6112
|
+
text_end_col: int,
|
6113
|
+
) -> dict:
|
6114
|
+
cells = {"datarn": {}, "datacn": {}, "dropdown": {}, "checkbox": {}}
|
6115
|
+
for r in range(text_start_row, text_end_row):
|
6116
|
+
datarn = r if self.all_rows_displayed else self.displayed_rows[r]
|
6117
|
+
cells["datarn"][r] = datarn
|
6118
|
+
for c in range(text_start_col, text_end_col):
|
6119
|
+
if c in cells["datacn"]:
|
6120
|
+
datacn = cells["datacn"][c]
|
6121
|
+
else:
|
6122
|
+
datacn = c if self.all_columns_displayed else self.displayed_columns[c]
|
6123
|
+
cells["datacn"][c] = datacn
|
6124
|
+
if kwargs := self.get_cell_kwargs(datarn, datacn, key="dropdown"):
|
6125
|
+
cells["dropdown"][(datarn, datacn)] = kwargs
|
6126
|
+
elif kwargs := self.get_cell_kwargs(datarn, datacn, key="checkbox"):
|
6127
|
+
cells["checkbox"][(datarn, datacn)] = kwargs
|
6128
|
+
cells[(datarn, datacn)] = self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
|
6129
|
+
return cells
|
6130
|
+
|
6131
|
+
def wrap_get_char_w(self, c: str) -> int:
|
6132
|
+
self.txt_measure_canvas.itemconfig(
|
6133
|
+
self.txt_measure_canvas_text,
|
6134
|
+
text=_test_str + c,
|
6135
|
+
font=self.table_font,
|
6136
|
+
)
|
6137
|
+
b = self.txt_measure_canvas.bbox(self.txt_measure_canvas_text)
|
6138
|
+
if c in self.char_widths[self.table_font]:
|
6139
|
+
return self.char_widths[self.table_font][c]
|
6140
|
+
else:
|
6141
|
+
wd = b[2] - b[0] - self.table_test_str_w
|
6142
|
+
self.char_widths[self.table_font][c] = wd
|
6143
|
+
return wd
|
6144
|
+
|
5814
6145
|
def main_table_redraw_grid_and_text(
|
5815
6146
|
self,
|
5816
6147
|
redraw_header: bool = False,
|
5817
6148
|
redraw_row_index: bool = False,
|
5818
6149
|
redraw_table: bool = True,
|
5819
6150
|
setting_views: bool = False,
|
6151
|
+
set_scrollregion: bool = True,
|
5820
6152
|
) -> bool:
|
5821
6153
|
try:
|
5822
6154
|
can_width = self.winfo_width()
|
@@ -5838,29 +6170,33 @@ class MainTable(tk.Canvas):
|
|
5838
6170
|
last_col_line_pos + self.PAR.ops.empty_horizontal + 2,
|
5839
6171
|
last_row_line_pos + self.PAR.ops.empty_vertical + 2,
|
5840
6172
|
)
|
5841
|
-
if setting_views or scrollregion != self.scrollregion:
|
5842
|
-
|
6173
|
+
if set_scrollregion and (setting_views or scrollregion != self.scrollregion):
|
6174
|
+
try:
|
6175
|
+
self.configure(scrollregion=scrollregion)
|
6176
|
+
except Exception:
|
6177
|
+
return False
|
5843
6178
|
self.scrollregion = scrollregion
|
5844
|
-
|
5845
|
-
|
5846
|
-
|
6179
|
+
if (
|
6180
|
+
not self.CH.configure_scrollregion(last_col_line_pos)
|
6181
|
+
or not self.RI.configure_scrollregion(last_row_line_pos)
|
6182
|
+
or setting_views
|
6183
|
+
):
|
5847
6184
|
return False
|
5848
6185
|
|
5849
6186
|
scrollpos_top = self.canvasy(0)
|
5850
6187
|
scrollpos_bot = self.canvasy(can_height)
|
5851
6188
|
scrollpos_left = self.canvasx(0)
|
5852
6189
|
scrollpos_right = self.canvasx(can_width)
|
5853
|
-
|
5854
6190
|
grid_start_row = bisect_left(self.row_positions, scrollpos_top)
|
5855
6191
|
grid_end_row = bisect_right(self.row_positions, scrollpos_bot)
|
5856
6192
|
grid_start_col = bisect_left(self.col_positions, scrollpos_left)
|
5857
6193
|
grid_end_col = bisect_right(self.col_positions, scrollpos_right)
|
5858
|
-
|
5859
6194
|
text_start_row = grid_start_row - 1 if grid_start_row else grid_start_row
|
5860
6195
|
text_end_row = grid_end_row - 1 if grid_end_row == len(self.row_positions) else grid_end_row
|
5861
6196
|
text_start_col = grid_start_col - 1 if grid_start_col else grid_start_col
|
5862
6197
|
text_end_col = grid_end_col - 1 if grid_end_col == len(self.col_positions) else grid_end_col
|
5863
6198
|
|
6199
|
+
# check if auto resizing row index
|
5864
6200
|
changed_w = False
|
5865
6201
|
if self.PAR.ops.auto_resize_row_index and redraw_row_index and self.show_index:
|
5866
6202
|
changed_w = self.RI.auto_set_index_width(
|
@@ -5873,7 +6209,10 @@ class MainTable(tk.Canvas):
|
|
5873
6209
|
for widget in (self, self.RI, self.CH, self.TL):
|
5874
6210
|
widget.update_idletasks()
|
5875
6211
|
return False
|
5876
|
-
|
6212
|
+
# important vars
|
6213
|
+
x_stop = min(last_col_line_pos, scrollpos_right)
|
6214
|
+
y_stop = min(last_row_line_pos, scrollpos_bot)
|
6215
|
+
# manage find window
|
5877
6216
|
if self.find_window.open:
|
5878
6217
|
w, h, x, y = self.get_find_window_dimensions_coords(w_width=self.winfo_width())
|
5879
6218
|
self.coords(self.find_window.canvas_id, x, y)
|
@@ -5883,19 +6222,71 @@ class MainTable(tk.Canvas):
|
|
5883
6222
|
height=h,
|
5884
6223
|
state="normal",
|
5885
6224
|
)
|
5886
|
-
|
5887
|
-
self.disp_text = {}
|
5888
|
-
self.hidd_high.update(self.disp_high)
|
5889
|
-
self.disp_high = {}
|
5890
|
-
self.hidd_grid.update(self.disp_grid)
|
5891
|
-
self.disp_grid = {}
|
5892
|
-
self.hidd_dropdown.update(self.disp_dropdown)
|
5893
|
-
self.disp_dropdown = {}
|
5894
|
-
self.hidd_checkbox.update(self.disp_checkbox)
|
5895
|
-
self.disp_checkbox = {}
|
5896
|
-
x_stop = min(last_col_line_pos, scrollpos_right)
|
5897
|
-
y_stop = min(last_row_line_pos, scrollpos_bot)
|
6225
|
+
# redraw table
|
5898
6226
|
if redraw_table:
|
6227
|
+
# reset canvas item storage
|
6228
|
+
self.hidd_text.update(self.disp_text)
|
6229
|
+
self.disp_text = {}
|
6230
|
+
self.hidd_high.update(self.disp_high)
|
6231
|
+
self.disp_high = {}
|
6232
|
+
self.hidd_grid.update(self.disp_grid)
|
6233
|
+
self.disp_grid = {}
|
6234
|
+
self.hidd_dropdown.update(self.disp_dropdown)
|
6235
|
+
self.disp_dropdown = {}
|
6236
|
+
self.hidd_checkbox.update(self.disp_checkbox)
|
6237
|
+
self.disp_checkbox = {}
|
6238
|
+
# manage horizontal grid lines
|
6239
|
+
if self.PAR.ops.show_horizontal_grid and row_pos_exists:
|
6240
|
+
if self.PAR.ops.horizontal_grid_to_end_of_window:
|
6241
|
+
x_grid_stop = scrollpos_right + can_width
|
6242
|
+
else:
|
6243
|
+
if last_col_line_pos > scrollpos_right:
|
6244
|
+
x_grid_stop = x_stop + 1
|
6245
|
+
else:
|
6246
|
+
x_grid_stop = x_stop - 1
|
6247
|
+
self.redraw_gridline(
|
6248
|
+
points=tuple(
|
6249
|
+
chain.from_iterable(
|
6250
|
+
(
|
6251
|
+
scrollpos_left - 1,
|
6252
|
+
self.row_positions[r],
|
6253
|
+
x_grid_stop,
|
6254
|
+
self.row_positions[r],
|
6255
|
+
scrollpos_left - 1,
|
6256
|
+
self.row_positions[r],
|
6257
|
+
scrollpos_left - 1,
|
6258
|
+
self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
|
6259
|
+
)
|
6260
|
+
for r in range(grid_start_row, grid_end_row)
|
6261
|
+
)
|
6262
|
+
)
|
6263
|
+
)
|
6264
|
+
# manage vertical grid lines
|
6265
|
+
if self.PAR.ops.show_vertical_grid and col_pos_exists:
|
6266
|
+
if self.PAR.ops.vertical_grid_to_end_of_window:
|
6267
|
+
y_grid_stop = scrollpos_bot + can_height
|
6268
|
+
else:
|
6269
|
+
if last_row_line_pos > scrollpos_bot:
|
6270
|
+
y_grid_stop = y_stop + 1
|
6271
|
+
else:
|
6272
|
+
y_grid_stop = y_stop - 1
|
6273
|
+
self.redraw_gridline(
|
6274
|
+
points=tuple(
|
6275
|
+
chain.from_iterable(
|
6276
|
+
(
|
6277
|
+
self.col_positions[c],
|
6278
|
+
scrollpos_top - 1,
|
6279
|
+
self.col_positions[c],
|
6280
|
+
y_grid_stop,
|
6281
|
+
self.col_positions[c],
|
6282
|
+
scrollpos_top - 1,
|
6283
|
+
self.col_positions[c + 1] if len(self.col_positions) - 1 > c else self.col_positions[c],
|
6284
|
+
scrollpos_top - 1,
|
6285
|
+
)
|
6286
|
+
for c in range(grid_start_col, grid_end_col)
|
6287
|
+
)
|
6288
|
+
),
|
6289
|
+
)
|
5899
6290
|
font = self.PAR.ops.table_font
|
5900
6291
|
dd_coords = self.dropdown.get_coords()
|
5901
6292
|
selections = self.get_redraw_selections(text_start_row, grid_end_row, text_start_col, grid_end_col)
|
@@ -5927,17 +6318,23 @@ class MainTable(tk.Canvas):
|
|
5927
6318
|
)
|
5928
6319
|
else:
|
5929
6320
|
override = tuple()
|
6321
|
+
allow_overflow = self.PAR.ops.allow_cell_overflow
|
6322
|
+
wrap = self.PAR.ops.table_wrap
|
6323
|
+
cells = self._redraw_precache_cells(
|
6324
|
+
text_start_row=text_start_row,
|
6325
|
+
text_end_row=text_end_row,
|
6326
|
+
text_start_col=text_start_col,
|
6327
|
+
text_end_col=text_end_col,
|
6328
|
+
)
|
5930
6329
|
for r in range(text_start_row, text_end_row):
|
5931
6330
|
rtopgridln = self.row_positions[r]
|
5932
6331
|
rbotgridln = self.row_positions[r + 1]
|
5933
|
-
|
5934
|
-
continue
|
5935
|
-
datarn = self.datarn(r)
|
6332
|
+
datarn = cells["datarn"][r]
|
5936
6333
|
|
5937
6334
|
for c in range(text_start_col, text_end_col):
|
5938
6335
|
cleftgridln = self.col_positions[c]
|
5939
6336
|
crightgridln = self.col_positions[c + 1]
|
5940
|
-
datacn =
|
6337
|
+
datacn = cells["datacn"][c]
|
5941
6338
|
fill, dd_drawn = self.redraw_highlight_get_text_fg(
|
5942
6339
|
r=r,
|
5943
6340
|
c=c,
|
@@ -5957,13 +6354,14 @@ class MainTable(tk.Canvas):
|
|
5957
6354
|
)
|
5958
6355
|
if not (align := self.get_cell_kwargs(datarn, datacn, key="align")):
|
5959
6356
|
align = self.align
|
5960
|
-
|
5961
|
-
|
5962
|
-
|
5963
|
-
|
5964
|
-
|
6357
|
+
|
6358
|
+
if kwargs := cells["dropdown"].get((datarn, datacn), None):
|
6359
|
+
max_width = crightgridln - cleftgridln - self.table_txt_height - 5
|
6360
|
+
if align.endswith("w"):
|
6361
|
+
draw_x = cleftgridln + 2
|
6362
|
+
elif align.endswith("e"):
|
5965
6363
|
draw_x = crightgridln - 5 - self.table_txt_height
|
5966
|
-
elif align
|
6364
|
+
elif align.endswith("n"):
|
5967
6365
|
draw_x = cleftgridln + ceil((crightgridln - cleftgridln - self.table_txt_height) / 2)
|
5968
6366
|
self.redraw_dropdown(
|
5969
6367
|
cleftgridln,
|
@@ -5973,25 +6371,27 @@ class MainTable(tk.Canvas):
|
|
5973
6371
|
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.table_grid_fg,
|
5974
6372
|
outline=fill,
|
5975
6373
|
draw_outline=not dd_drawn,
|
5976
|
-
draw_arrow=
|
6374
|
+
draw_arrow=max_width >= 5,
|
5977
6375
|
open_=dd_coords == (r, c),
|
5978
6376
|
)
|
5979
6377
|
else:
|
5980
|
-
|
5981
|
-
if align
|
5982
|
-
draw_x = cleftgridln +
|
5983
|
-
elif align
|
5984
|
-
draw_x = crightgridln -
|
5985
|
-
elif align
|
6378
|
+
max_width = crightgridln - cleftgridln - 2
|
6379
|
+
if align.endswith("w"):
|
6380
|
+
draw_x = cleftgridln + 2
|
6381
|
+
elif align.endswith("e"):
|
6382
|
+
draw_x = crightgridln - 2
|
6383
|
+
elif align.endswith("n"):
|
5986
6384
|
draw_x = cleftgridln + floor((crightgridln - cleftgridln) / 2)
|
5987
|
-
|
5988
|
-
if
|
6385
|
+
|
6386
|
+
if (
|
6387
|
+
kwargs := cells["checkbox"].get((datarn, datacn), None)
|
6388
|
+
) and max_width > self.table_txt_height + 1:
|
5989
6389
|
box_w = self.table_txt_height + 1
|
5990
|
-
if align
|
6390
|
+
if align.endswith("w"):
|
5991
6391
|
draw_x += box_w + 3
|
5992
|
-
elif align
|
6392
|
+
elif align.endswith("n"):
|
5993
6393
|
draw_x += ceil(box_w / 2) + 1
|
5994
|
-
|
6394
|
+
max_width -= box_w + 4
|
5995
6395
|
try:
|
5996
6396
|
draw_check = bool(self.data[datarn][datacn])
|
5997
6397
|
except Exception:
|
@@ -6005,27 +6405,77 @@ class MainTable(tk.Canvas):
|
|
6005
6405
|
outline="",
|
6006
6406
|
draw_check=draw_check,
|
6007
6407
|
)
|
6008
|
-
|
6408
|
+
text = cells[(datarn, datacn)]
|
6009
6409
|
if (
|
6010
|
-
not
|
6011
|
-
or
|
6012
|
-
or (align
|
6013
|
-
or (align
|
6014
|
-
or (align == "center" and cleftgridln + 5 > scrollpos_right)
|
6410
|
+
not text
|
6411
|
+
or (align.endswith("w") and draw_x > scrollpos_right)
|
6412
|
+
or (align.endswith("e") and cleftgridln + 5 > scrollpos_right)
|
6413
|
+
or (align.endswith("n") and cleftgridln + 5 > scrollpos_right)
|
6015
6414
|
):
|
6016
6415
|
continue
|
6017
|
-
|
6018
|
-
|
6019
|
-
|
6020
|
-
|
6021
|
-
|
6416
|
+
if allow_overflow and not kwargs:
|
6417
|
+
if align.endswith("w"):
|
6418
|
+
max_width += sum(self._overflow(cells, range(c + 1, text_end_col), datarn))
|
6419
|
+
elif align.endswith("e"):
|
6420
|
+
max_width += sum(self._overflow(cells, reversed(range(text_start_col, c)), datarn))
|
6421
|
+
elif align.endswith("n"):
|
6422
|
+
...
|
6423
|
+
if max_width <= 1:
|
6424
|
+
continue
|
6425
|
+
start_line = max(0, int((scrollpos_top - rtopgridln) / self.table_txt_height))
|
6426
|
+
draw_y = rtopgridln + 3 + (start_line * self.table_txt_height)
|
6427
|
+
gen_lines = wrap_text(
|
6428
|
+
text=text,
|
6429
|
+
max_width=max_width,
|
6430
|
+
max_lines=int((rbotgridln - rtopgridln - 2) / self.table_txt_height),
|
6431
|
+
char_width_fn=self.wrap_get_char_w,
|
6432
|
+
widths=self.char_widths[font],
|
6433
|
+
wrap=wrap,
|
6434
|
+
start_line=start_line,
|
6435
|
+
)
|
6436
|
+
if align.endswith(("w", "e")):
|
6437
|
+
if self.hidd_text:
|
6438
|
+
iid, showing = self.hidd_text.popitem()
|
6439
|
+
self.coords(iid, draw_x, draw_y)
|
6440
|
+
if showing:
|
6441
|
+
self.itemconfig(
|
6442
|
+
iid,
|
6443
|
+
text="\n".join(gen_lines),
|
6444
|
+
fill=fill,
|
6445
|
+
font=font,
|
6446
|
+
anchor=align,
|
6447
|
+
)
|
6448
|
+
else:
|
6449
|
+
self.itemconfig(
|
6450
|
+
iid,
|
6451
|
+
text="\n".join(gen_lines),
|
6452
|
+
fill=fill,
|
6453
|
+
font=font,
|
6454
|
+
anchor=align,
|
6455
|
+
state="normal",
|
6456
|
+
)
|
6457
|
+
self.tag_raise(iid)
|
6458
|
+
else:
|
6459
|
+
iid = self.create_text(
|
6460
|
+
draw_x,
|
6461
|
+
draw_y,
|
6462
|
+
text="\n".join(gen_lines),
|
6463
|
+
fill=fill,
|
6464
|
+
font=font,
|
6465
|
+
anchor=align,
|
6466
|
+
tags="t",
|
6467
|
+
)
|
6468
|
+
self.disp_text[iid] = True
|
6469
|
+
|
6470
|
+
elif align.endswith("n"):
|
6471
|
+
for text in gen_lines:
|
6022
6472
|
if self.hidd_text:
|
6023
6473
|
iid, showing = self.hidd_text.popitem()
|
6024
6474
|
self.coords(iid, draw_x, draw_y)
|
6025
6475
|
if showing:
|
6026
6476
|
self.itemconfig(
|
6027
6477
|
iid,
|
6028
|
-
text=
|
6478
|
+
text=text,
|
6029
6479
|
fill=fill,
|
6030
6480
|
font=font,
|
6031
6481
|
anchor=align,
|
@@ -6033,7 +6483,7 @@ class MainTable(tk.Canvas):
|
|
6033
6483
|
else:
|
6034
6484
|
self.itemconfig(
|
6035
6485
|
iid,
|
6036
|
-
text=
|
6486
|
+
text=text,
|
6037
6487
|
fill=fill,
|
6038
6488
|
font=font,
|
6039
6489
|
anchor=align,
|
@@ -6044,96 +6494,14 @@ class MainTable(tk.Canvas):
|
|
6044
6494
|
iid = self.create_text(
|
6045
6495
|
draw_x,
|
6046
6496
|
draw_y,
|
6047
|
-
text=
|
6497
|
+
text=text,
|
6048
6498
|
fill=fill,
|
6049
6499
|
font=font,
|
6050
6500
|
anchor=align,
|
6051
|
-
|
6501
|
+
tags="t",
|
6052
6502
|
)
|
6053
6503
|
self.disp_text[iid] = True
|
6054
|
-
|
6055
|
-
if (wd := wd[2] - wd[0]) > mw:
|
6056
|
-
if align == "w":
|
6057
|
-
txt = txt[: int(len(txt) * (mw / wd))]
|
6058
|
-
self.itemconfig(iid, text=txt)
|
6059
|
-
wd = self.bbox(iid)
|
6060
|
-
while wd[2] - wd[0] > mw:
|
6061
|
-
txt = txt[:-1]
|
6062
|
-
self.itemconfig(iid, text=txt)
|
6063
|
-
wd = self.bbox(iid)
|
6064
|
-
elif align == "e":
|
6065
|
-
txt = txt[len(txt) - int(len(txt) * (mw / wd)) :]
|
6066
|
-
self.itemconfig(iid, text=txt)
|
6067
|
-
wd = self.bbox(iid)
|
6068
|
-
while wd[2] - wd[0] > mw:
|
6069
|
-
txt = txt[1:]
|
6070
|
-
self.itemconfig(iid, text=txt)
|
6071
|
-
wd = self.bbox(iid)
|
6072
|
-
elif align == "center":
|
6073
|
-
tmod = ceil((len(txt) - int(len(txt) * (mw / wd))) / 2)
|
6074
|
-
txt = txt[tmod - 1 : -tmod]
|
6075
|
-
self.itemconfig(iid, text=txt)
|
6076
|
-
wd = self.bbox(iid)
|
6077
|
-
while wd[2] - wd[0] > mw:
|
6078
|
-
txt = txt[next(self.c_align_cyc)]
|
6079
|
-
self.itemconfig(iid, text=txt)
|
6080
|
-
wd = self.bbox(iid)
|
6081
|
-
self.coords(iid, draw_x, draw_y)
|
6082
|
-
draw_y += self.table_xtra_lines_increment
|
6083
|
-
if draw_y + self.table_half_txt_height - 1 > rbotgridln:
|
6084
|
-
break
|
6085
|
-
# manage horizontal grid lines
|
6086
|
-
if self.PAR.ops.show_horizontal_grid and row_pos_exists:
|
6087
|
-
if self.PAR.ops.horizontal_grid_to_end_of_window:
|
6088
|
-
x_grid_stop = scrollpos_right + can_width
|
6089
|
-
else:
|
6090
|
-
if last_col_line_pos > scrollpos_right:
|
6091
|
-
x_grid_stop = x_stop + 1
|
6092
|
-
else:
|
6093
|
-
x_grid_stop = x_stop - 1
|
6094
|
-
self.redraw_gridline(
|
6095
|
-
points=tuple(
|
6096
|
-
chain.from_iterable(
|
6097
|
-
(
|
6098
|
-
scrollpos_left - 1,
|
6099
|
-
self.row_positions[r],
|
6100
|
-
x_grid_stop,
|
6101
|
-
self.row_positions[r],
|
6102
|
-
scrollpos_left - 1,
|
6103
|
-
self.row_positions[r],
|
6104
|
-
scrollpos_left - 1,
|
6105
|
-
self.row_positions[r + 1] if len(self.row_positions) - 1 > r else self.row_positions[r],
|
6106
|
-
)
|
6107
|
-
for r in range(grid_start_row, grid_end_row)
|
6108
|
-
)
|
6109
|
-
)
|
6110
|
-
)
|
6111
|
-
# manage vertical grid lines
|
6112
|
-
if self.PAR.ops.show_vertical_grid and col_pos_exists:
|
6113
|
-
if self.PAR.ops.vertical_grid_to_end_of_window:
|
6114
|
-
y_grid_stop = scrollpos_bot + can_height
|
6115
|
-
else:
|
6116
|
-
if last_row_line_pos > scrollpos_bot:
|
6117
|
-
y_grid_stop = y_stop + 1
|
6118
|
-
else:
|
6119
|
-
y_grid_stop = y_stop - 1
|
6120
|
-
self.redraw_gridline(
|
6121
|
-
points=tuple(
|
6122
|
-
chain.from_iterable(
|
6123
|
-
(
|
6124
|
-
self.col_positions[c],
|
6125
|
-
scrollpos_top - 1,
|
6126
|
-
self.col_positions[c],
|
6127
|
-
y_grid_stop,
|
6128
|
-
self.col_positions[c],
|
6129
|
-
scrollpos_top - 1,
|
6130
|
-
self.col_positions[c + 1] if len(self.col_positions) - 1 > c else self.col_positions[c],
|
6131
|
-
scrollpos_top - 1,
|
6132
|
-
)
|
6133
|
-
for c in range(grid_start_col, grid_end_col)
|
6134
|
-
)
|
6135
|
-
),
|
6136
|
-
)
|
6504
|
+
draw_y += self.table_txt_height
|
6137
6505
|
for dct in (
|
6138
6506
|
self.hidd_text,
|
6139
6507
|
self.hidd_high,
|
@@ -6166,6 +6534,7 @@ class MainTable(tk.Canvas):
|
|
6166
6534
|
text_end_col=text_end_col,
|
6167
6535
|
scrollpos_right=scrollpos_right,
|
6168
6536
|
col_pos_exists=col_pos_exists,
|
6537
|
+
set_scrollregion=set_scrollregion,
|
6169
6538
|
)
|
6170
6539
|
if redraw_row_index and self.show_index:
|
6171
6540
|
self.RI.redraw_grid_and_text(
|
@@ -6178,6 +6547,7 @@ class MainTable(tk.Canvas):
|
|
6178
6547
|
text_end_row=text_end_row,
|
6179
6548
|
scrollpos_bot=scrollpos_bot,
|
6180
6549
|
row_pos_exists=row_pos_exists,
|
6550
|
+
set_scrollregion=set_scrollregion,
|
6181
6551
|
)
|
6182
6552
|
event_data = {"sheetname": "", "header": redraw_header, "row_index": redraw_row_index, "table": redraw_table}
|
6183
6553
|
self.PAR.emit_event("<<SheetRedrawn>>", data=event_data)
|
@@ -6902,7 +7272,7 @@ class MainTable(tk.Canvas):
|
|
6902
7272
|
return False
|
6903
7273
|
self.hide_text_editor()
|
6904
7274
|
if not self.see(r=r, c=c, check_cell_visibility=True):
|
6905
|
-
self.
|
7275
|
+
self.main_table_redraw_grid_and_text(True, True)
|
6906
7276
|
x = self.col_positions[c]
|
6907
7277
|
y = self.row_positions[r]
|
6908
7278
|
w = self.col_positions[c + 1] - x + 1
|
@@ -6971,7 +7341,7 @@ class MainTable(tk.Canvas):
|
|
6971
7341
|
> curr_height
|
6972
7342
|
):
|
6973
7343
|
new_height = min(
|
6974
|
-
curr_height + self.
|
7344
|
+
curr_height + self.table_txt_height,
|
6975
7345
|
self.scrollregion[3] - self.scrollregion[1] - self.row_positions[r],
|
6976
7346
|
)
|
6977
7347
|
if new_height != curr_height:
|
@@ -7218,7 +7588,7 @@ class MainTable(tk.Canvas):
|
|
7218
7588
|
for i, v in enumerate(self.get_cell_kwargs(datarn, datacn, key="dropdown")["values"]):
|
7219
7589
|
v_numlines = len(v.split("\n") if isinstance(v, str) else f"{v}".split("\n"))
|
7220
7590
|
if v_numlines > 1:
|
7221
|
-
win_h +=
|
7591
|
+
win_h += 8 + (v_numlines * self.table_txt_height) # end of cell
|
7222
7592
|
else:
|
7223
7593
|
win_h += self.min_row_height
|
7224
7594
|
if i == 5:
|
@@ -7669,7 +8039,7 @@ class MainTable(tk.Canvas):
|
|
7669
8039
|
else:
|
7670
8040
|
# assumed given formatter class has get_data_with_valid_check()
|
7671
8041
|
return f"{value.get_data_with_valid_check()}"
|
7672
|
-
return "" if value is None else f"{value}"
|
8042
|
+
return "" if value is None else value if isinstance(value, str) else f"{value}"
|
7673
8043
|
|
7674
8044
|
def get_cell_data(
|
7675
8045
|
self,
|
@@ -7682,7 +8052,11 @@ class MainTable(tk.Canvas):
|
|
7682
8052
|
) -> object:
|
7683
8053
|
if get_displayed:
|
7684
8054
|
return self.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True)
|
7685
|
-
value =
|
8055
|
+
value = (
|
8056
|
+
self.data[datarn][datacn]
|
8057
|
+
if len(self.data) > datarn and len(self.data[datarn]) > datacn
|
8058
|
+
else self.get_value_for_empty_cell(datarn, datacn)
|
8059
|
+
)
|
7686
8060
|
kwargs = self.get_cell_kwargs(datarn, datacn, key="format")
|
7687
8061
|
if kwargs and kwargs["formatter"] is not None:
|
7688
8062
|
value = value.value # assumed given formatter class has value attribute
|