tksheet 7.4.4__py3-none-any.whl → 7.4.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tksheet/__init__.py +1 -1
- tksheet/column_headers.py +56 -58
- tksheet/constants.py +2 -2
- tksheet/formatters.py +20 -36
- tksheet/functions.py +13 -23
- tksheet/main_table.py +185 -334
- tksheet/other_classes.py +10 -16
- tksheet/row_index.py +87 -65
- tksheet/sheet.py +99 -105
- tksheet/sorting.py +4 -4
- tksheet/text_editor.py +9 -3
- tksheet/top_left_rectangle.py +5 -6
- {tksheet-7.4.4.dist-info → tksheet-7.4.5.dist-info}/METADATA +4 -2
- tksheet-7.4.5.dist-info/RECORD +22 -0
- {tksheet-7.4.4.dist-info → tksheet-7.4.5.dist-info}/WHEEL +1 -1
- tksheet-7.4.4.dist-info/RECORD +0 -22
- {tksheet-7.4.4.dist-info → tksheet-7.4.5.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.4.4.dist-info → tksheet-7.4.5.dist-info}/top_level.txt +0 -0
tksheet/other_classes.py
CHANGED
@@ -105,9 +105,7 @@ class SpanRange:
|
|
105
105
|
return reversed(range(self.from_, self.upto_))
|
106
106
|
|
107
107
|
def __contains__(self, n: int) -> bool:
|
108
|
-
|
109
|
-
return True
|
110
|
-
return False
|
108
|
+
return n >= self.from_ and n < self.upto_
|
111
109
|
|
112
110
|
def __eq__(self, v: SpanRange) -> bool:
|
113
111
|
return self.from_ == v.from_ and self.upto_ == v.upto_
|
@@ -189,11 +187,13 @@ class Span(dict):
|
|
189
187
|
|
190
188
|
def format(
|
191
189
|
self,
|
192
|
-
formatter_options: dict =
|
190
|
+
formatter_options: dict | None = None,
|
193
191
|
formatter_class: object = None,
|
194
192
|
redraw: bool = True,
|
195
193
|
**kwargs,
|
196
194
|
) -> Span:
|
195
|
+
if formatter_options is None:
|
196
|
+
formatter_options = {}
|
197
197
|
return self["widget"].format(
|
198
198
|
self,
|
199
199
|
formatter_options={"formatter": formatter_class, **formatter_options, **kwargs},
|
@@ -232,9 +232,9 @@ class Span(dict):
|
|
232
232
|
|
233
233
|
def dropdown(
|
234
234
|
self,
|
235
|
-
values: list =
|
235
|
+
values: list[object] | None = None,
|
236
236
|
edit_data: bool = True,
|
237
|
-
set_values: dict[tuple[int, int], object] =
|
237
|
+
set_values: dict[tuple[int, int], object] | None = None,
|
238
238
|
set_value: object = None,
|
239
239
|
state: str = "normal",
|
240
240
|
redraw: bool = True,
|
@@ -246,9 +246,9 @@ class Span(dict):
|
|
246
246
|
) -> Span:
|
247
247
|
return self["widget"].dropdown(
|
248
248
|
self,
|
249
|
-
values=values,
|
249
|
+
values=[] if values is None else values,
|
250
250
|
edit_data=edit_data,
|
251
|
-
set_values=set_values,
|
251
|
+
set_values={} if set_values is None else set_values,
|
252
252
|
set_value=set_value,
|
253
253
|
state=state,
|
254
254
|
redraw=redraw,
|
@@ -406,19 +406,13 @@ class Span(dict):
|
|
406
406
|
@property
|
407
407
|
def rows(self) -> SpanRange:
|
408
408
|
rng_from_r = 0 if self["from_r"] is None else self["from_r"]
|
409
|
-
if self["upto_r"] is None
|
410
|
-
rng_upto_r = self["widget"].total_rows()
|
411
|
-
else:
|
412
|
-
rng_upto_r = self["upto_r"]
|
409
|
+
rng_upto_r = self["widget"].total_rows() if self["upto_r"] is None else self["upto_r"]
|
413
410
|
return SpanRange(rng_from_r, rng_upto_r)
|
414
411
|
|
415
412
|
@property
|
416
413
|
def columns(self) -> SpanRange:
|
417
414
|
rng_from_c = 0 if self["from_c"] is None else self["from_c"]
|
418
|
-
if self["upto_c"] is None
|
419
|
-
rng_upto_c = self["widget"].total_columns()
|
420
|
-
else:
|
421
|
-
rng_upto_c = self["upto_c"]
|
415
|
+
rng_upto_c = self["widget"].total_columns() if self["upto_c"] is None else self["upto_c"]
|
422
416
|
return SpanRange(rng_from_c, rng_upto_c)
|
423
417
|
|
424
418
|
@property
|
tksheet/row_index.py
CHANGED
@@ -91,7 +91,7 @@ class RowIndex(tk.Canvas):
|
|
91
91
|
self.rc_delete_row_enabled = False
|
92
92
|
self.edit_cell_enabled = False
|
93
93
|
self.visible_row_dividers = {}
|
94
|
-
self.row_width_resize_bbox =
|
94
|
+
self.row_width_resize_bbox = ()
|
95
95
|
self.rsz_w = None
|
96
96
|
self.rsz_h = None
|
97
97
|
self.currently_resizing_width = False
|
@@ -249,28 +249,32 @@ class RowIndex(tk.Canvas):
|
|
249
249
|
def shift_b1_press(self, event: object) -> None:
|
250
250
|
self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
251
251
|
r = self.MT.identify_row(y=event.y)
|
252
|
-
if (
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
self.
|
265
|
-
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
266
|
-
sel_event = self.MT.get_select_event(being_drawn_item=self.being_drawn_item)
|
267
|
-
try_binding(self.shift_selection_binding_func, sel_event)
|
268
|
-
self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
|
269
|
-
elif r_selected:
|
270
|
-
self.dragged_row = DraggedRowColumn(
|
271
|
-
dragged=r,
|
272
|
-
to_move=sorted(self.MT.get_selected_rows()),
|
252
|
+
if (
|
253
|
+
(self.drag_and_drop_enabled or self.row_selection_enabled)
|
254
|
+
and self.rsz_h is None
|
255
|
+
and self.rsz_w is None
|
256
|
+
and r < len(self.MT.row_positions) - 1
|
257
|
+
):
|
258
|
+
r_selected = self.MT.row_selected(r)
|
259
|
+
if not r_selected and self.row_selection_enabled:
|
260
|
+
if self.MT.selected and self.MT.selected.type_ == "rows":
|
261
|
+
r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
|
262
|
+
self.MT.deselect("all", redraw=False)
|
263
|
+
self.being_drawn_item = self.MT.create_selection_box(
|
264
|
+
*self.get_shift_select_box(r, r_to_sel), "rows"
|
273
265
|
)
|
266
|
+
self.MT.set_currently_selected(r_to_sel, c_to_sel, self.being_drawn_item)
|
267
|
+
else:
|
268
|
+
self.being_drawn_item = self.select_row(r, run_binding_func=False)
|
269
|
+
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
270
|
+
sel_event = self.MT.get_select_event(being_drawn_item=self.being_drawn_item)
|
271
|
+
try_binding(self.shift_selection_binding_func, sel_event)
|
272
|
+
self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
|
273
|
+
elif r_selected:
|
274
|
+
self.dragged_row = DraggedRowColumn(
|
275
|
+
dragged=r,
|
276
|
+
to_move=sorted(self.MT.get_selected_rows()),
|
277
|
+
)
|
274
278
|
|
275
279
|
def get_shift_select_box(self, r: int, min_r: int) -> tuple[int, int, int, int, str]:
|
276
280
|
if r >= min_r:
|
@@ -354,12 +358,11 @@ class RowIndex(tk.Canvas):
|
|
354
358
|
self.rsz_w = None
|
355
359
|
except Exception:
|
356
360
|
self.rsz_w = None
|
357
|
-
if not mouse_over_resize:
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
self.MT.current_cursor = "hand2"
|
361
|
+
if not mouse_over_resize and self.MT.row_selected(self.MT.identify_row(event, allow_end=False)):
|
362
|
+
mouse_over_selected = True
|
363
|
+
if self.MT.current_cursor != "hand2":
|
364
|
+
self.config(cursor="hand2")
|
365
|
+
self.MT.current_cursor = "hand2"
|
363
366
|
if not mouse_over_resize and not mouse_over_selected:
|
364
367
|
self.MT.reset_mouse_motion_creations()
|
365
368
|
try_binding(self.extra_motion_func, event)
|
@@ -1231,7 +1234,7 @@ class RowIndex(tk.Canvas):
|
|
1231
1234
|
def set_width_of_index_to_text(
|
1232
1235
|
self,
|
1233
1236
|
text: None | str = None,
|
1234
|
-
only_rows: list =
|
1237
|
+
only_rows: list[int] | None = None,
|
1235
1238
|
) -> int:
|
1236
1239
|
self.fix_index()
|
1237
1240
|
w = self.ops.default_row_index_width
|
@@ -1245,7 +1248,7 @@ class RowIndex(tk.Canvas):
|
|
1245
1248
|
if (tw := b[2] - b[0] + 10) > w:
|
1246
1249
|
w = tw
|
1247
1250
|
elif text is None:
|
1248
|
-
w = self.get_index_text_width(only_rows=only_rows)
|
1251
|
+
w = self.get_index_text_width(only_rows=[] if only_rows is None else only_rows)
|
1249
1252
|
if w > self.ops.max_index_width:
|
1250
1253
|
w = int(self.ops.max_index_width)
|
1251
1254
|
self.set_width(w, set_TL=True)
|
@@ -1641,9 +1644,8 @@ class RowIndex(tk.Canvas):
|
|
1641
1644
|
row_pos_exists: bool,
|
1642
1645
|
set_scrollregion: bool,
|
1643
1646
|
) -> bool:
|
1644
|
-
if set_scrollregion:
|
1645
|
-
|
1646
|
-
return False
|
1647
|
+
if set_scrollregion and not self.configure_scrollregion(last_row_line_pos=last_row_line_pos):
|
1648
|
+
return False
|
1647
1649
|
self.hidd_text.update(self.disp_text)
|
1648
1650
|
self.disp_text = {}
|
1649
1651
|
self.hidd_high.update(self.disp_high)
|
@@ -1983,7 +1985,7 @@ class RowIndex(tk.Canvas):
|
|
1983
1985
|
self.text_editor.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
|
1984
1986
|
return False
|
1985
1987
|
self.hide_text_editor()
|
1986
|
-
if not self.MT.see(r
|
1988
|
+
if not self.MT.see(r, 0, keep_yscroll=True):
|
1987
1989
|
self.MT.main_table_redraw_grid_and_text(True, True)
|
1988
1990
|
x = 0
|
1989
1991
|
y = self.MT.row_positions[r]
|
@@ -2433,12 +2435,13 @@ class RowIndex(tk.Canvas):
|
|
2433
2435
|
return False
|
2434
2436
|
elif "checkbox" in kwargs:
|
2435
2437
|
return is_bool_like(value)
|
2436
|
-
elif self.cell_equal_to(datarn, value):
|
2437
|
-
return False
|
2438
|
-
elif (kwargs := kwargs.get("dropdown", {})) and kwargs["validate_input"] and value not in kwargs["values"]:
|
2439
|
-
return False
|
2440
2438
|
else:
|
2441
|
-
return
|
2439
|
+
return not (
|
2440
|
+
self.cell_equal_to(datarn, value)
|
2441
|
+
or (kwargs := kwargs.get("dropdown", {}))
|
2442
|
+
and kwargs["validate_input"]
|
2443
|
+
and value not in kwargs["values"]
|
2444
|
+
)
|
2442
2445
|
|
2443
2446
|
def cell_equal_to(self, datarn: int, value: object) -> bool:
|
2444
2447
|
self.fix_index(datarn)
|
@@ -2683,12 +2686,10 @@ class RowIndex(tk.Canvas):
|
|
2683
2686
|
else:
|
2684
2687
|
move_to_index = len(self.tree[new_parent].children)
|
2685
2688
|
move_to_row = self.tree_rns[new_parent]
|
2686
|
-
if new_parent == self.tree[item].parent
|
2687
|
-
|
2688
|
-
|
2689
|
-
|
2690
|
-
break
|
2691
|
-
move_to_row += sum(1 for _ in self.get_iid_descendants(ciid)) + 1
|
2689
|
+
_find = move_to_index + 1 if new_parent == self.tree[item].parent else move_to_index
|
2690
|
+
move_to_row += _find + sum(
|
2691
|
+
self.num_descendants(cid) for cid in islice(self.tree[new_parent].children, _find)
|
2692
|
+
)
|
2692
2693
|
insert_row = move_to_row + 1
|
2693
2694
|
else:
|
2694
2695
|
num_top_nodes = sum(1 for _ in self.gen_top_nodes())
|
@@ -2708,7 +2709,7 @@ class RowIndex(tk.Canvas):
|
|
2708
2709
|
disp_insert_row = None
|
2709
2710
|
|
2710
2711
|
else:
|
2711
|
-
iids =
|
2712
|
+
iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
|
2712
2713
|
iids_descendants = {iid: set(self.get_iid_descendants(iid)) for iid in iids}
|
2713
2714
|
|
2714
2715
|
# remove descendants in iids to move
|
@@ -2730,10 +2731,7 @@ class RowIndex(tk.Canvas):
|
|
2730
2731
|
# max_from = max(event_data.moved.rows)
|
2731
2732
|
min_to = min(event_data["moved"]["rows"]["data"].values())
|
2732
2733
|
max_to = max(event_data["moved"]["rows"]["data"].values())
|
2733
|
-
if min_from <= min_to
|
2734
|
-
insert_row = max_to
|
2735
|
-
else:
|
2736
|
-
insert_row = min_to
|
2734
|
+
insert_row = max_to if min_from <= min_to else min_to
|
2737
2735
|
move_to_iid = self.MT._row_index[insert_row].iid
|
2738
2736
|
|
2739
2737
|
move_to_index = self.PAR.index(move_to_iid)
|
@@ -2755,7 +2753,7 @@ class RowIndex(tk.Canvas):
|
|
2755
2753
|
if (disp_from_row := self.MT.try_disprn(self.tree_rns[item])) is not None:
|
2756
2754
|
event_data["moved"]["rows"]["displayed"] = {disp_from_row: disp_insert_row}
|
2757
2755
|
else:
|
2758
|
-
event_data["moved"]["rows"]["displayed"] = {
|
2756
|
+
event_data["moved"]["rows"]["displayed"] = {(): disp_insert_row}
|
2759
2757
|
|
2760
2758
|
if any(self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows):
|
2761
2759
|
event_data["moved"]["rows"] = {}
|
@@ -2778,8 +2776,8 @@ class RowIndex(tk.Canvas):
|
|
2778
2776
|
data_new_idxs = event_data["moved"]["rows"]["data"]
|
2779
2777
|
data_old_idxs = dict(zip(data_new_idxs.values(), data_new_idxs))
|
2780
2778
|
|
2781
|
-
if
|
2782
|
-
del event_data["moved"]["rows"]["displayed"][
|
2779
|
+
if () in event_data["moved"]["rows"]["displayed"]:
|
2780
|
+
del event_data["moved"]["rows"]["displayed"][()]
|
2783
2781
|
|
2784
2782
|
if event_data["moved"]["rows"]["displayed"]:
|
2785
2783
|
event_data["moved"]["rows"]["displayed"] = get_new_indexes(
|
@@ -2848,7 +2846,7 @@ class RowIndex(tk.Canvas):
|
|
2848
2846
|
row_ctr = next(reversed(mapping.values())) + 1
|
2849
2847
|
|
2850
2848
|
if disp_mapping := event_data["moved"]["rows"]["displayed"]:
|
2851
|
-
if
|
2849
|
+
if () in disp_mapping:
|
2852
2850
|
disp_row_ctr = next(reversed(disp_mapping.values()))
|
2853
2851
|
else:
|
2854
2852
|
disp_row_ctr = next(reversed(disp_mapping.values())) + 1
|
@@ -2907,24 +2905,48 @@ class RowIndex(tk.Canvas):
|
|
2907
2905
|
|
2908
2906
|
def ancestors_all_open(self, iid: str, stop_at: str = "") -> bool:
|
2909
2907
|
if stop_at:
|
2910
|
-
for
|
2911
|
-
if
|
2908
|
+
for i in self.get_iid_ancestors(iid):
|
2909
|
+
if i == stop_at:
|
2912
2910
|
return True
|
2913
|
-
elif
|
2911
|
+
elif i not in self.tree_open_ids:
|
2914
2912
|
return False
|
2915
2913
|
return True
|
2916
2914
|
return all(map(self.tree_open_ids.__contains__, self.get_iid_ancestors(iid)))
|
2917
2915
|
|
2918
2916
|
def get_iid_ancestors(self, iid: str) -> Generator[str]:
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
2917
|
+
current_iid = iid
|
2918
|
+
while self.tree[current_iid].parent:
|
2919
|
+
parent_iid = self.tree[current_iid].parent
|
2920
|
+
yield parent_iid
|
2921
|
+
current_iid = parent_iid
|
2922
2922
|
|
2923
2923
|
def get_iid_descendants(self, iid: str, check_open: bool = False) -> Generator[str]:
|
2924
|
-
|
2925
|
-
|
2926
|
-
|
2927
|
-
|
2924
|
+
tree = self.tree
|
2925
|
+
stack = [iter(tree[iid].children)]
|
2926
|
+
while stack:
|
2927
|
+
top_iterator = stack[-1]
|
2928
|
+
try:
|
2929
|
+
ciid = next(top_iterator)
|
2930
|
+
yield ciid
|
2931
|
+
if tree[ciid].children and (not check_open or ciid in self.tree_open_ids):
|
2932
|
+
stack.append(iter(tree[ciid].children))
|
2933
|
+
except StopIteration:
|
2934
|
+
stack.pop()
|
2935
|
+
|
2936
|
+
def num_descendants(self, iid: str) -> int:
|
2937
|
+
tree = self.tree
|
2938
|
+
stack = [iter(tree[iid].children)]
|
2939
|
+
num = 0
|
2940
|
+
while stack:
|
2941
|
+
top_iterator = stack[-1]
|
2942
|
+
try:
|
2943
|
+
ciid = next(top_iterator)
|
2944
|
+
num += 1
|
2945
|
+
if tree[ciid].children:
|
2946
|
+
stack.append(iter(tree[ciid].children))
|
2947
|
+
except StopIteration:
|
2948
|
+
stack.pop()
|
2949
|
+
return num
|
2928
2950
|
|
2929
2951
|
def items_parent(self, iid: str) -> str:
|
2930
2952
|
if self.tree[iid].parent:
|
@@ -3086,5 +3108,5 @@ class RowIndex(tk.Canvas):
|
|
3086
3108
|
{self.tree_rns[iid] for iid in self.PAR.get_children() if self.tree[iid].parent},
|
3087
3109
|
deselect_all=False,
|
3088
3110
|
data_indexes=True,
|
3089
|
-
row_heights=
|
3111
|
+
row_heights=row_heights is not False,
|
3090
3112
|
)
|