tksheet 7.4.3__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 +2 -2
- tksheet/column_headers.py +74 -69
- tksheet/constants.py +2 -2
- tksheet/formatters.py +20 -36
- tksheet/functions.py +37 -47
- tksheet/main_table.py +239 -376
- tksheet/other_classes.py +10 -16
- tksheet/row_index.py +116 -83
- tksheet/sheet.py +133 -152
- tksheet/sheet_options.py +2 -0
- tksheet/sorting.py +279 -66
- tksheet/text_editor.py +9 -3
- tksheet/top_left_rectangle.py +5 -6
- {tksheet-7.4.3.dist-info → tksheet-7.4.5.dist-info}/METADATA +4 -2
- tksheet-7.4.5.dist-info/RECORD +22 -0
- {tksheet-7.4.3.dist-info → tksheet-7.4.5.dist-info}/WHEEL +1 -1
- tksheet-7.4.3.dist-info/RECORD +0 -22
- {tksheet-7.4.3.dist-info → tksheet-7.4.5.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.4.3.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)
|
@@ -900,6 +903,8 @@ class RowIndex(tk.Canvas):
|
|
900
903
|
rows = list(range(0, len(self.MT.row_positions) - 1))
|
901
904
|
event_data = self.MT.new_event_dict("edit_table")
|
902
905
|
try_binding(self.MT.extra_begin_sort_cells_func, event_data)
|
906
|
+
if key is None:
|
907
|
+
key = self.PAR.ops.sort_key
|
903
908
|
for r in rows:
|
904
909
|
datarn = self.MT.datarn(r)
|
905
910
|
for c, val in enumerate(sort_row(self.MT.data[datarn], reverse=reverse, key=key)):
|
@@ -943,6 +948,8 @@ class RowIndex(tk.Canvas):
|
|
943
948
|
return event_data
|
944
949
|
row = self.MT.selected.row
|
945
950
|
if try_binding(self.ri_extra_begin_sort_cols_func, event_data, "begin_move_columns"):
|
951
|
+
if key is None:
|
952
|
+
key = self.PAR.ops.sort_key
|
946
953
|
sorted_indices, data_new_idxs = sort_columns_by_row(self.MT.data, row=row, reverse=reverse, key=key)
|
947
954
|
disp_new_idxs = {}
|
948
955
|
if self.MT.all_columns_displayed:
|
@@ -1227,7 +1234,7 @@ class RowIndex(tk.Canvas):
|
|
1227
1234
|
def set_width_of_index_to_text(
|
1228
1235
|
self,
|
1229
1236
|
text: None | str = None,
|
1230
|
-
only_rows: list =
|
1237
|
+
only_rows: list[int] | None = None,
|
1231
1238
|
) -> int:
|
1232
1239
|
self.fix_index()
|
1233
1240
|
w = self.ops.default_row_index_width
|
@@ -1241,7 +1248,7 @@ class RowIndex(tk.Canvas):
|
|
1241
1248
|
if (tw := b[2] - b[0] + 10) > w:
|
1242
1249
|
w = tw
|
1243
1250
|
elif text is None:
|
1244
|
-
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)
|
1245
1252
|
if w > self.ops.max_index_width:
|
1246
1253
|
w = int(self.ops.max_index_width)
|
1247
1254
|
self.set_width(w, set_TL=True)
|
@@ -1637,9 +1644,8 @@ class RowIndex(tk.Canvas):
|
|
1637
1644
|
row_pos_exists: bool,
|
1638
1645
|
set_scrollregion: bool,
|
1639
1646
|
) -> bool:
|
1640
|
-
if set_scrollregion:
|
1641
|
-
|
1642
|
-
return False
|
1647
|
+
if set_scrollregion and not self.configure_scrollregion(last_row_line_pos=last_row_line_pos):
|
1648
|
+
return False
|
1643
1649
|
self.hidd_text.update(self.disp_text)
|
1644
1650
|
self.disp_text = {}
|
1645
1651
|
self.hidd_high.update(self.disp_high)
|
@@ -1979,7 +1985,7 @@ class RowIndex(tk.Canvas):
|
|
1979
1985
|
self.text_editor.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
|
1980
1986
|
return False
|
1981
1987
|
self.hide_text_editor()
|
1982
|
-
if not self.MT.see(r
|
1988
|
+
if not self.MT.see(r, 0, keep_yscroll=True):
|
1983
1989
|
self.MT.main_table_redraw_grid_and_text(True, True)
|
1984
1990
|
x = 0
|
1985
1991
|
y = self.MT.row_positions[r]
|
@@ -2424,16 +2430,18 @@ class RowIndex(tk.Canvas):
|
|
2424
2430
|
self.MT._row_index[datarn] = value
|
2425
2431
|
|
2426
2432
|
def input_valid_for_cell(self, datarn: int, value: object, check_readonly: bool = True) -> bool:
|
2427
|
-
|
2433
|
+
kwargs = self.get_cell_kwargs(datarn, key=None)
|
2434
|
+
if check_readonly and "readonly" in kwargs:
|
2428
2435
|
return False
|
2429
|
-
|
2436
|
+
elif "checkbox" in kwargs:
|
2430
2437
|
return is_bool_like(value)
|
2431
|
-
|
2432
|
-
return
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2438
|
+
else:
|
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
|
+
)
|
2437
2445
|
|
2438
2446
|
def cell_equal_to(self, datarn: int, value: object) -> bool:
|
2439
2447
|
self.fix_index(datarn)
|
@@ -2495,12 +2503,13 @@ class RowIndex(tk.Canvas):
|
|
2495
2503
|
if self.ops.treeview:
|
2496
2504
|
iid = self.new_iid()
|
2497
2505
|
return Node(text=iid, iid=iid, parent=self.get_row_parent(datarn))
|
2498
|
-
|
2506
|
+
kwargs = self.get_cell_kwargs(datarn, key=None, cell=r_ops)
|
2507
|
+
if "checkbox" in kwargs:
|
2499
2508
|
return False
|
2500
|
-
kwargs
|
2501
|
-
if kwargs and kwargs["validate_input"] and kwargs["values"]:
|
2509
|
+
elif (kwargs := kwargs.get("dropdown", {})) and kwargs["validate_input"] and kwargs["values"]:
|
2502
2510
|
return kwargs["values"][0]
|
2503
|
-
|
2511
|
+
else:
|
2512
|
+
return ""
|
2504
2513
|
|
2505
2514
|
def get_empty_index_seq(self, end: int, start: int = 0, r_ops: bool = True) -> list[object]:
|
2506
2515
|
return [self.get_value_for_empty_cell(datarn, r_ops=r_ops) for datarn in range(start, end)]
|
@@ -2567,10 +2576,11 @@ class RowIndex(tk.Canvas):
|
|
2567
2576
|
if redraw:
|
2568
2577
|
self.MT.refresh()
|
2569
2578
|
|
2570
|
-
def get_cell_kwargs(self, datarn: int, key: Hashable = "dropdown", cell: bool = True) -> dict:
|
2571
|
-
if cell and datarn in self.cell_options
|
2572
|
-
return self.cell_options[datarn][key
|
2573
|
-
|
2579
|
+
def get_cell_kwargs(self, datarn: int, key: Hashable | None = "dropdown", cell: bool = True) -> dict:
|
2580
|
+
if cell and datarn in self.cell_options:
|
2581
|
+
return self.cell_options[datarn] if key is None else self.cell_options[datarn].get(key, {})
|
2582
|
+
else:
|
2583
|
+
return {}
|
2574
2584
|
|
2575
2585
|
# Treeview Mode
|
2576
2586
|
|
@@ -2671,29 +2681,35 @@ class RowIndex(tk.Canvas):
|
|
2671
2681
|
new_parent = node_change[1]
|
2672
2682
|
move_to_index = node_change[2]
|
2673
2683
|
if new_parent:
|
2674
|
-
move_to_index
|
2675
|
-
move_to_index
|
2676
|
-
|
2677
|
-
|
2678
|
-
|
2684
|
+
if isinstance(move_to_index, int):
|
2685
|
+
move_to_index = min(move_to_index, len(self.tree[new_parent].children))
|
2686
|
+
else:
|
2687
|
+
move_to_index = len(self.tree[new_parent].children)
|
2688
|
+
move_to_row = self.tree_rns[new_parent]
|
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)
|
2679
2692
|
)
|
2693
|
+
insert_row = move_to_row + 1
|
2680
2694
|
else:
|
2681
2695
|
num_top_nodes = sum(1 for _ in self.gen_top_nodes())
|
2682
2696
|
if move_to_index is None:
|
2683
2697
|
move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
|
2684
2698
|
move_to_index = num_top_nodes
|
2699
|
+
insert_row = move_to_row
|
2685
2700
|
else:
|
2686
2701
|
move_to_row = self.PAR.top_index_row(move_to_index)
|
2702
|
+
insert_row = move_to_row
|
2687
2703
|
if move_to_row is None:
|
2688
2704
|
move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
|
2689
2705
|
move_to_index = num_top_nodes
|
2706
|
+
insert_row = move_to_row + 1
|
2690
2707
|
|
2691
2708
|
move_to_iid = self.MT._row_index[move_to_row].iid
|
2692
|
-
insert_row = move_to_row + 1
|
2693
2709
|
disp_insert_row = None
|
2694
2710
|
|
2695
2711
|
else:
|
2696
|
-
iids =
|
2712
|
+
iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
|
2697
2713
|
iids_descendants = {iid: set(self.get_iid_descendants(iid)) for iid in iids}
|
2698
2714
|
|
2699
2715
|
# remove descendants in iids to move
|
@@ -2715,10 +2731,7 @@ class RowIndex(tk.Canvas):
|
|
2715
2731
|
# max_from = max(event_data.moved.rows)
|
2716
2732
|
min_to = min(event_data["moved"]["rows"]["data"].values())
|
2717
2733
|
max_to = max(event_data["moved"]["rows"]["data"].values())
|
2718
|
-
if min_from <= min_to
|
2719
|
-
insert_row = max_to
|
2720
|
-
else:
|
2721
|
-
insert_row = min_to
|
2734
|
+
insert_row = max_to if min_from <= min_to else min_to
|
2722
2735
|
move_to_iid = self.MT._row_index[insert_row].iid
|
2723
2736
|
|
2724
2737
|
move_to_index = self.PAR.index(move_to_iid)
|
@@ -2733,14 +2746,14 @@ class RowIndex(tk.Canvas):
|
|
2733
2746
|
event_data["moved"]["rows"]["displayed"] = {}
|
2734
2747
|
if new_loc_is_displayed:
|
2735
2748
|
if disp_insert_row is None:
|
2736
|
-
if new_parent
|
2749
|
+
if new_parent or insert_row > move_to_row:
|
2737
2750
|
disp_insert_row = self.MT.disprn(self.tree_rns[move_to_iid]) + 1
|
2738
2751
|
else:
|
2739
|
-
disp_insert_row = self.MT.disprn(self.tree_rns[move_to_iid])
|
2752
|
+
disp_insert_row = self.MT.disprn(self.tree_rns[move_to_iid])
|
2740
2753
|
if (disp_from_row := self.MT.try_disprn(self.tree_rns[item])) is not None:
|
2741
2754
|
event_data["moved"]["rows"]["displayed"] = {disp_from_row: disp_insert_row}
|
2742
2755
|
else:
|
2743
|
-
event_data["moved"]["rows"]["displayed"] = {
|
2756
|
+
event_data["moved"]["rows"]["displayed"] = {(): disp_insert_row}
|
2744
2757
|
|
2745
2758
|
if any(self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows):
|
2746
2759
|
event_data["moved"]["rows"] = {}
|
@@ -2756,7 +2769,6 @@ class RowIndex(tk.Canvas):
|
|
2756
2769
|
index=move_to_index,
|
2757
2770
|
)
|
2758
2771
|
move_to_index += 1
|
2759
|
-
|
2760
2772
|
event_data["moved"]["rows"]["data"] = get_new_indexes(
|
2761
2773
|
insert_row,
|
2762
2774
|
event_data["moved"]["rows"]["data"],
|
@@ -2764,8 +2776,8 @@ class RowIndex(tk.Canvas):
|
|
2764
2776
|
data_new_idxs = event_data["moved"]["rows"]["data"]
|
2765
2777
|
data_old_idxs = dict(zip(data_new_idxs.values(), data_new_idxs))
|
2766
2778
|
|
2767
|
-
if
|
2768
|
-
del event_data["moved"]["rows"]["displayed"][
|
2779
|
+
if () in event_data["moved"]["rows"]["displayed"]:
|
2780
|
+
del event_data["moved"]["rows"]["displayed"][()]
|
2769
2781
|
|
2770
2782
|
if event_data["moved"]["rows"]["displayed"]:
|
2771
2783
|
event_data["moved"]["rows"]["displayed"] = get_new_indexes(
|
@@ -2782,7 +2794,6 @@ class RowIndex(tk.Canvas):
|
|
2782
2794
|
if not undo_modification and data_new_idxs:
|
2783
2795
|
if new_parent and (not self.PAR.item_displayed(new_parent) or new_parent not in self.tree_open_ids):
|
2784
2796
|
self.PAR.hide_rows(set(data_new_idxs.values()), data_indexes=True)
|
2785
|
-
|
2786
2797
|
if new_loc_is_displayed:
|
2787
2798
|
self.PAR.show_rows(
|
2788
2799
|
(r for r in data_new_idxs.values() if self.ancestors_all_open(self.MT._row_index[r].iid))
|
@@ -2835,7 +2846,7 @@ class RowIndex(tk.Canvas):
|
|
2835
2846
|
row_ctr = next(reversed(mapping.values())) + 1
|
2836
2847
|
|
2837
2848
|
if disp_mapping := event_data["moved"]["rows"]["displayed"]:
|
2838
|
-
if
|
2849
|
+
if () in disp_mapping:
|
2839
2850
|
disp_row_ctr = next(reversed(disp_mapping.values()))
|
2840
2851
|
else:
|
2841
2852
|
disp_row_ctr = next(reversed(disp_mapping.values())) + 1
|
@@ -2894,24 +2905,48 @@ class RowIndex(tk.Canvas):
|
|
2894
2905
|
|
2895
2906
|
def ancestors_all_open(self, iid: str, stop_at: str = "") -> bool:
|
2896
2907
|
if stop_at:
|
2897
|
-
for
|
2898
|
-
if
|
2908
|
+
for i in self.get_iid_ancestors(iid):
|
2909
|
+
if i == stop_at:
|
2899
2910
|
return True
|
2900
|
-
elif
|
2911
|
+
elif i not in self.tree_open_ids:
|
2901
2912
|
return False
|
2902
2913
|
return True
|
2903
2914
|
return all(map(self.tree_open_ids.__contains__, self.get_iid_ancestors(iid)))
|
2904
2915
|
|
2905
2916
|
def get_iid_ancestors(self, iid: str) -> Generator[str]:
|
2906
|
-
|
2907
|
-
|
2908
|
-
|
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
|
2909
2922
|
|
2910
2923
|
def get_iid_descendants(self, iid: str, check_open: bool = False) -> Generator[str]:
|
2911
|
-
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
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
|
2915
2950
|
|
2916
2951
|
def items_parent(self, iid: str) -> str:
|
2917
2952
|
if self.tree[iid].parent:
|
@@ -2959,9 +2994,7 @@ class RowIndex(tk.Canvas):
|
|
2959
2994
|
def move_pid_causes_recursive_loop(self, to_move_iid: str, move_to_parent: str) -> bool:
|
2960
2995
|
# if the parent the item is being moved under is one of the item's descendants
|
2961
2996
|
# then it is a recursive loop
|
2962
|
-
return
|
2963
|
-
move_to_parent == diid for diid in self.get_iid_descendants(to_move_iid)
|
2964
|
-
)
|
2997
|
+
return any(move_to_parent == diid for diid in self.get_iid_descendants(to_move_iid))
|
2965
2998
|
|
2966
2999
|
def tree_build(
|
2967
3000
|
self,
|
@@ -3075,5 +3108,5 @@ class RowIndex(tk.Canvas):
|
|
3075
3108
|
{self.tree_rns[iid] for iid in self.PAR.get_children() if self.tree[iid].parent},
|
3076
3109
|
deselect_all=False,
|
3077
3110
|
data_indexes=True,
|
3078
|
-
row_heights=
|
3111
|
+
row_heights=row_heights is not False,
|
3079
3112
|
)
|