tksheet 7.5.3__tar.gz → 7.5.5__tar.gz
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-7.5.3/tksheet.egg-info → tksheet-7.5.5}/PKG-INFO +1 -1
- {tksheet-7.5.3 → tksheet-7.5.5}/pyproject.toml +1 -1
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/__init__.py +1 -1
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/functions.py +43 -34
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/main_table.py +4 -6
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/other_classes.py +4 -4
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/row_index.py +39 -80
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/sheet.py +37 -23
- {tksheet-7.5.3 → tksheet-7.5.5/tksheet.egg-info}/PKG-INFO +1 -1
- {tksheet-7.5.3 → tksheet-7.5.5}/LICENSE.txt +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/README.md +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/setup.cfg +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/colors.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/column_headers.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/constants.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/find_window.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/formatters.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/sheet_options.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/sorting.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/text_editor.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/themes.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/tksheet_types.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet/top_left_rectangle.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.5.3 → tksheet-7.5.5}/tksheet.egg-info/top_level.txt +0 -0
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
6
6
|
name = "tksheet"
|
7
7
|
description = "Tkinter table / sheet and treeview widget"
|
8
8
|
readme = "README.md"
|
9
|
-
version = "7.5.
|
9
|
+
version = "7.5.5"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -765,6 +765,14 @@ def add_to_displayed(displayed: list[int], to_add: Iterable[int]) -> list[int]:
|
|
765
765
|
return displayed
|
766
766
|
|
767
767
|
|
768
|
+
def push_displayed(displayed: list[int], to_add: Iterable[int]) -> list[int]:
|
769
|
+
# assumes to_add is sorted
|
770
|
+
for i in to_add:
|
771
|
+
ins = bisect_left(displayed, i)
|
772
|
+
displayed[ins:] = [e + 1 for e in islice(displayed, ins, None)]
|
773
|
+
return displayed
|
774
|
+
|
775
|
+
|
768
776
|
def move_elements_by_mapping(
|
769
777
|
seq: list[Any],
|
770
778
|
new_idxs: dict[int, int],
|
@@ -853,18 +861,6 @@ def insert_items(
|
|
853
861
|
return seq
|
854
862
|
|
855
863
|
|
856
|
-
def del_placeholder_dict_key(
|
857
|
-
d: dict[Hashable, Any],
|
858
|
-
k: Hashable,
|
859
|
-
v: Any,
|
860
|
-
p: tuple = (),
|
861
|
-
) -> dict[Hashable, Any]:
|
862
|
-
if p in d:
|
863
|
-
del d[p]
|
864
|
-
d[k] = v
|
865
|
-
return d
|
866
|
-
|
867
|
-
|
868
864
|
def data_to_displayed_idxs(
|
869
865
|
to_convert: list[int],
|
870
866
|
displayed: list[int],
|
@@ -1207,14 +1203,14 @@ PATTERN_ALL = re.compile(r"^:$") # ":"
|
|
1207
1203
|
|
1208
1204
|
def span_a2i(a: str) -> int | None:
|
1209
1205
|
n = 0
|
1210
|
-
for c in a:
|
1206
|
+
for c in a.upper():
|
1211
1207
|
n = n * 26 + ord(c) - ORD_A + 1
|
1212
1208
|
return n - 1
|
1213
1209
|
|
1214
1210
|
|
1215
1211
|
def span_a2n(a: str) -> int | None:
|
1216
1212
|
n = 0
|
1217
|
-
for c in a:
|
1213
|
+
for c in a.upper():
|
1218
1214
|
n = n * 26 + ord(c) - ORD_A + 1
|
1219
1215
|
return n
|
1220
1216
|
|
@@ -1251,7 +1247,7 @@ def key_to_span(
|
|
1251
1247
|
return coords_to_span(widget=widget, from_r=None, from_c=None, upto_r=None, upto_c=None)
|
1252
1248
|
|
1253
1249
|
# Validate input type
|
1254
|
-
elif not isinstance(key, (str, int, slice,
|
1250
|
+
elif not isinstance(key, (str, int, slice, tuple, list)):
|
1255
1251
|
return f"Key type must be either str, int, list, tuple or slice, not '{type(key).__name__}'."
|
1256
1252
|
|
1257
1253
|
try:
|
@@ -1277,22 +1273,34 @@ def key_to_span(
|
|
1277
1273
|
)
|
1278
1274
|
|
1279
1275
|
# Sequence key: various span formats
|
1280
|
-
elif isinstance(key, (
|
1281
|
-
if (
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1276
|
+
elif isinstance(key, (tuple, list)):
|
1277
|
+
if len(key) == 2:
|
1278
|
+
if (isinstance(key[0], int) or key[0] is None) and (isinstance(key[1], int) or key[1] is None):
|
1279
|
+
# Single cell or partial span: (row, col)
|
1280
|
+
r_int = isinstance(key[0], int)
|
1281
|
+
c_int = isinstance(key[1], int)
|
1282
|
+
return span_dict(
|
1283
|
+
from_r=key[0] if r_int else 0,
|
1284
|
+
from_c=key[1] if c_int else 0,
|
1285
|
+
upto_r=key[0] + 1 if r_int else None,
|
1286
|
+
upto_c=key[1] + 1 if c_int else None,
|
1287
|
+
widget=widget,
|
1288
|
+
)
|
1289
|
+
|
1290
|
+
elif isinstance(key[0], int) and isinstance(key[1], str):
|
1291
|
+
# Single cell with column letter: (row 0, col A)
|
1292
|
+
c_int = span_a2i(key[1])
|
1293
|
+
return span_dict(
|
1294
|
+
from_r=key[0],
|
1295
|
+
from_c=c_int,
|
1296
|
+
upto_r=key[0] + 1,
|
1297
|
+
upto_c=c_int + 1,
|
1298
|
+
widget=widget,
|
1299
|
+
)
|
1300
|
+
|
1301
|
+
else:
|
1302
|
+
return f"'{key}' could not be converted to span."
|
1303
|
+
|
1296
1304
|
elif len(key) == 4:
|
1297
1305
|
# Full span coordinates: (from_r, from_c, upto_r, upto_c)
|
1298
1306
|
return coords_to_span(
|
@@ -1302,7 +1310,7 @@ def key_to_span(
|
|
1302
1310
|
upto_r=key[2],
|
1303
1311
|
upto_c=key[3],
|
1304
1312
|
)
|
1305
|
-
elif len(key) == 2 and all(isinstance(k, (
|
1313
|
+
elif len(key) == 2 and all(isinstance(k, (tuple, list)) for k in key):
|
1306
1314
|
# Start and end points: ((from_r, from_c), (upto_r, upto_c))
|
1307
1315
|
return coords_to_span(
|
1308
1316
|
widget=widget,
|
@@ -1339,11 +1347,12 @@ def key_to_span(
|
|
1339
1347
|
widget=widget,
|
1340
1348
|
)
|
1341
1349
|
elif m := PATTERN_COL.match(key):
|
1350
|
+
c_int = span_a2i(m[1])
|
1342
1351
|
return span_dict(
|
1343
1352
|
from_r=None,
|
1344
|
-
from_c=
|
1353
|
+
from_c=c_int,
|
1345
1354
|
upto_r=None,
|
1346
|
-
upto_c=
|
1355
|
+
upto_c=c_int + 1,
|
1347
1356
|
widget=widget,
|
1348
1357
|
)
|
1349
1358
|
elif m := PATTERN_CELL.match(key):
|
@@ -1967,6 +1967,7 @@ class MainTable(tk.Canvas):
|
|
1967
1967
|
)
|
1968
1968
|
else:
|
1969
1969
|
self.recreate_all_selection_boxes()
|
1970
|
+
|
1970
1971
|
return data_new_idxs, disp_new_idxs, event_data
|
1971
1972
|
|
1972
1973
|
def get_max_row_idx(self, maxidx: int | None = None) -> int:
|
@@ -2117,6 +2118,7 @@ class MainTable(tk.Canvas):
|
|
2117
2118
|
event_data["selection_boxes"] = modification["selection_boxes"]
|
2118
2119
|
event_data["selected"] = modification["selected"]
|
2119
2120
|
saved_cells = False
|
2121
|
+
|
2120
2122
|
if modification["added"]["rows"] or modification["added"]["columns"]:
|
2121
2123
|
event_data = self.save_cells_using_modification(modification, event_data)
|
2122
2124
|
saved_cells = True
|
@@ -5629,12 +5631,8 @@ class MainTable(tk.Canvas):
|
|
5629
5631
|
return {
|
5630
5632
|
"row_positions": list(self.row_positions),
|
5631
5633
|
"col_positions": list(self.col_positions),
|
5632
|
-
"displayed_rows":
|
5633
|
-
|
5634
|
-
else list(self.displayed_rows),
|
5635
|
-
"displayed_columns": int(self.displayed_columns)
|
5636
|
-
if isinstance(self.displayed_columns, int)
|
5637
|
-
else list(self.displayed_columns),
|
5634
|
+
"displayed_rows": list(self.displayed_rows),
|
5635
|
+
"displayed_columns": list(self.displayed_columns),
|
5638
5636
|
"all_rows_displayed": bool(self.all_rows_displayed),
|
5639
5637
|
"saved_row_heights": dict(self.saved_row_heights),
|
5640
5638
|
"saved_column_widths": dict(self.saved_column_widths),
|
@@ -481,10 +481,10 @@ class Node:
|
|
481
481
|
parent: str = "",
|
482
482
|
children: list[str] | None = None,
|
483
483
|
) -> None:
|
484
|
-
self.text = text
|
485
|
-
self.iid = iid
|
486
|
-
self.parent = parent
|
487
|
-
self.children = children if children else []
|
484
|
+
self.text: str = text
|
485
|
+
self.iid: str = iid
|
486
|
+
self.parent: str = parent
|
487
|
+
self.children: list[str] = children if children else []
|
488
488
|
|
489
489
|
|
490
490
|
class StorageBase:
|
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
3
3
|
import tkinter as tk
|
4
4
|
from collections import defaultdict
|
5
5
|
from collections.abc import Callable, Generator, Hashable, Iterator, Sequence
|
6
|
-
from contextlib import suppress
|
7
6
|
from functools import partial
|
8
7
|
from itertools import islice, repeat
|
9
8
|
from math import ceil
|
@@ -22,7 +21,6 @@ from .formatters import is_bool_like, try_to_bool
|
|
22
21
|
from .functions import (
|
23
22
|
add_to_displayed,
|
24
23
|
consecutive_ranges,
|
25
|
-
del_placeholder_dict_key,
|
26
24
|
event_dict,
|
27
25
|
event_has_char_key,
|
28
26
|
event_opens_dropdown_or_checkbox,
|
@@ -34,6 +32,7 @@ from .functions import (
|
|
34
32
|
mod_event_val,
|
35
33
|
new_tk_event,
|
36
34
|
num2alpha,
|
35
|
+
push_displayed,
|
37
36
|
rounded_box_coords,
|
38
37
|
stored_event_dict,
|
39
38
|
try_b_index,
|
@@ -839,7 +838,7 @@ class RowIndex(tk.Canvas):
|
|
839
838
|
move_heights=self.ops.row_drag_and_drop_perform,
|
840
839
|
event_data=event_data,
|
841
840
|
)
|
842
|
-
if data_new_idxs
|
841
|
+
if data_new_idxs:
|
843
842
|
event_data["moved"]["rows"] = {
|
844
843
|
"data": data_new_idxs,
|
845
844
|
"displayed": disp_new_idxs,
|
@@ -2634,13 +2633,17 @@ class RowIndex(tk.Canvas):
|
|
2634
2633
|
|
2635
2634
|
# handle displaying the new rows
|
2636
2635
|
event_data["added"]["rows"]["row_heights"] = {}
|
2636
|
+
# parent exists and it's displayed and it's open
|
2637
2637
|
if parent and self.PAR.item_displayed(parent) and parent in self.tree_open_ids:
|
2638
2638
|
self.MT.displayed_rows = add_to_displayed(self.MT.displayed_rows, event_data["added"]["rows"]["index"])
|
2639
2639
|
disp_idx = self.MT.disprn(self.rns[a_node.iid]) # first node, they're contiguous because not undo
|
2640
2640
|
h = self.MT.get_default_row_height()
|
2641
2641
|
for i in range(len(event_data["added"]["rows"]["index"])):
|
2642
2642
|
event_data["added"]["rows"]["row_heights"][disp_idx + i] = h
|
2643
|
-
|
2643
|
+
# parent exists and either it's not displayed or not open
|
2644
|
+
elif parent:
|
2645
|
+
self.MT.displayed_rows = push_displayed(self.MT.displayed_rows, event_data["added"]["rows"]["index"])
|
2646
|
+
# no parent, top level
|
2644
2647
|
elif not parent:
|
2645
2648
|
self.MT.displayed_rows = add_to_displayed(self.MT.displayed_rows, event_data["added"]["rows"]["index"])
|
2646
2649
|
h = self.MT.get_default_row_height()
|
@@ -2675,34 +2678,38 @@ class RowIndex(tk.Canvas):
|
|
2675
2678
|
moved_rows = [self.rns[item]]
|
2676
2679
|
new_parent = node_change[1]
|
2677
2680
|
move_to_index = node_change[2]
|
2681
|
+
# new parent exists
|
2678
2682
|
if new_parent:
|
2683
|
+
new_par_cn = self.iid_children(new_parent)
|
2684
|
+
# determine index
|
2679
2685
|
if isinstance(move_to_index, int):
|
2680
|
-
move_to_index = min(move_to_index, len(
|
2686
|
+
move_to_index = min(move_to_index, len(new_par_cn))
|
2681
2687
|
else:
|
2682
|
-
move_to_index = len(
|
2683
|
-
|
2684
|
-
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2688
|
+
move_to_index = len(new_par_cn)
|
2689
|
+
# determine insert row
|
2690
|
+
if not new_par_cn:
|
2691
|
+
insert_row = self.rns[new_parent] + 1
|
2692
|
+
elif move_to_index >= len(new_par_cn):
|
2693
|
+
insert_row = self.rns[new_par_cn[-1]] + self.num_descendants(new_par_cn[-1]) + 1
|
2694
|
+
elif new_parent == self.iid_parent(item):
|
2695
|
+
if move_to_index <= self.PAR.index(item):
|
2696
|
+
# Insert before the sibling at move_to_index
|
2697
|
+
insert_row = self.rns[new_par_cn[move_to_index]]
|
2698
|
+
else:
|
2699
|
+
# Insert after the sibling at move_to_index
|
2700
|
+
insert_row = self.rns[new_par_cn[move_to_index]]
|
2701
|
+
insert_row += 1 + self.num_descendants(new_par_cn[move_to_index])
|
2702
|
+
else:
|
2703
|
+
insert_row = self.rns[new_par_cn[move_to_index]]
|
2704
|
+
# no new parent
|
2689
2705
|
else:
|
2690
|
-
|
2691
|
-
if move_to_index
|
2692
|
-
|
2693
|
-
move_to_index = num_top_nodes
|
2694
|
-
insert_row = move_to_row
|
2706
|
+
# determine index
|
2707
|
+
if isinstance(move_to_index, int):
|
2708
|
+
move_to_index = min(move_to_index, sum(1 for _ in self.gen_top_nodes()))
|
2695
2709
|
else:
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
|
2700
|
-
move_to_index = num_top_nodes
|
2701
|
-
insert_row = move_to_row + 1
|
2702
|
-
|
2703
|
-
move_to_iid = self.MT._row_index[move_to_row].iid
|
2704
|
-
disp_insert_row = None
|
2705
|
-
|
2710
|
+
move_to_index = sum(1 for _ in self.gen_top_nodes())
|
2711
|
+
# determine insert row
|
2712
|
+
insert_row = self.PAR._get_id_insert_row(move_to_index, new_parent)
|
2706
2713
|
else:
|
2707
2714
|
iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
|
2708
2715
|
iids_descendants = {iid: set(self.get_iid_descendants(iid)) for iid in iids}
|
@@ -2713,21 +2720,18 @@ class RowIndex(tk.Canvas):
|
|
2713
2720
|
item = self.MT._row_index[moved_rows[0]].iid
|
2714
2721
|
|
2715
2722
|
if isinstance(event_data.value, int):
|
2716
|
-
|
2717
|
-
if disp_insert_row >= len(self.MT.displayed_rows):
|
2723
|
+
if event_data.value >= len(self.MT.displayed_rows):
|
2718
2724
|
insert_row = len(self.MT._row_index)
|
2719
2725
|
else:
|
2720
|
-
insert_row = self.MT.datarn(
|
2726
|
+
insert_row = self.MT.datarn(event_data.value)
|
2721
2727
|
move_to_iid = self.MT._row_index[min(insert_row, len(self.MT._row_index) - 1)].iid
|
2722
2728
|
|
2723
2729
|
else:
|
2724
|
-
disp_insert_row = None
|
2725
2730
|
min_from = min(event_data["moved"]["rows"]["data"])
|
2726
2731
|
# max_from = max(event_data.moved.rows)
|
2727
2732
|
min_to = min(event_data["moved"]["rows"]["data"].values())
|
2728
2733
|
max_to = max(event_data["moved"]["rows"]["data"].values())
|
2729
2734
|
insert_row = max_to if min_from <= min_to else min_to
|
2730
|
-
move_to_row = insert_row
|
2731
2735
|
move_to_iid = self.MT._row_index[insert_row].iid
|
2732
2736
|
|
2733
2737
|
move_to_index = self.PAR.index(move_to_iid)
|
@@ -2738,19 +2742,7 @@ class RowIndex(tk.Canvas):
|
|
2738
2742
|
new_loc_is_displayed = not new_parent or (
|
2739
2743
|
new_parent and new_parent in self.tree_open_ids and self.PAR.item_displayed(new_parent)
|
2740
2744
|
)
|
2741
|
-
# deal with displayed mapping
|
2742
2745
|
event_data["moved"]["rows"]["displayed"] = {}
|
2743
|
-
with suppress(Exception):
|
2744
|
-
if new_loc_is_displayed:
|
2745
|
-
if disp_insert_row is None:
|
2746
|
-
if new_parent or insert_row > move_to_row:
|
2747
|
-
disp_insert_row = self.MT.disprn(self.rns[move_to_iid]) + 1
|
2748
|
-
else:
|
2749
|
-
disp_insert_row = self.MT.disprn(self.rns[move_to_iid])
|
2750
|
-
if (disp_from_row := self.MT.try_disprn(self.rns[item])) is not None:
|
2751
|
-
event_data["moved"]["rows"]["displayed"] = {disp_from_row: disp_insert_row}
|
2752
|
-
else:
|
2753
|
-
event_data["moved"]["rows"]["displayed"] = {(): disp_insert_row}
|
2754
2746
|
|
2755
2747
|
if any(self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows):
|
2756
2748
|
event_data["moved"]["rows"] = {}
|
@@ -2772,15 +2764,6 @@ class RowIndex(tk.Canvas):
|
|
2772
2764
|
)
|
2773
2765
|
data_new_idxs = event_data["moved"]["rows"]["data"]
|
2774
2766
|
data_old_idxs = {v: k for k, v in data_new_idxs.items()}
|
2775
|
-
|
2776
|
-
if () in event_data["moved"]["rows"]["displayed"]:
|
2777
|
-
del event_data["moved"]["rows"]["displayed"][()]
|
2778
|
-
|
2779
|
-
if event_data["moved"]["rows"]["displayed"]:
|
2780
|
-
event_data["moved"]["rows"]["displayed"] = get_new_indexes(
|
2781
|
-
disp_insert_row,
|
2782
|
-
event_data["moved"]["rows"]["displayed"],
|
2783
|
-
)
|
2784
2767
|
disp_new_idxs = event_data["moved"]["rows"]["displayed"]
|
2785
2768
|
|
2786
2769
|
if data_new_idxs:
|
@@ -2817,8 +2800,7 @@ class RowIndex(tk.Canvas):
|
|
2817
2800
|
# its the same parent, we're just moving index
|
2818
2801
|
if parent == item_node.parent:
|
2819
2802
|
event_data = self.copy_nodes((item, parent), event_data)
|
2820
|
-
|
2821
|
-
parent_node.children.insert(index, parent_node.children.pop(pop_index))
|
2803
|
+
parent_node.children.insert(index, parent_node.children.pop(parent_node.children.index(item)))
|
2822
2804
|
|
2823
2805
|
else:
|
2824
2806
|
if item_node.parent:
|
@@ -2842,29 +2824,16 @@ class RowIndex(tk.Canvas):
|
|
2842
2824
|
mapping = event_data["moved"]["rows"]["data"]
|
2843
2825
|
row_ctr = next(reversed(mapping.values())) + 1
|
2844
2826
|
|
2845
|
-
if disp_mapping := event_data["moved"]["rows"]["displayed"]:
|
2846
|
-
if () in disp_mapping:
|
2847
|
-
disp_row_ctr = next(reversed(disp_mapping.values()))
|
2848
|
-
else:
|
2849
|
-
disp_row_ctr = next(reversed(disp_mapping.values())) + 1
|
2850
|
-
|
2851
2827
|
rn = self.rns[item]
|
2852
2828
|
if rn not in mapping:
|
2853
2829
|
mapping[rn] = row_ctr
|
2854
2830
|
row_ctr += 1
|
2855
|
-
if disp_mapping and (disp_from := self.MT.try_disprn(rn)) is not None:
|
2856
|
-
disp_mapping = del_placeholder_dict_key(disp_mapping, disp_from, disp_row_ctr)
|
2857
|
-
disp_row_ctr += 1
|
2858
2831
|
|
2859
2832
|
for did in self.get_iid_descendants(item):
|
2860
2833
|
mapping[self.rns[did]] = row_ctr
|
2861
2834
|
row_ctr += 1
|
2862
|
-
if disp_mapping and (disp_from := self.MT.try_disprn(self.rns[did])) is not None:
|
2863
|
-
disp_mapping = del_placeholder_dict_key(disp_mapping, disp_from, disp_row_ctr)
|
2864
|
-
disp_row_ctr += 1
|
2865
2835
|
|
2866
2836
|
event_data["moved"]["rows"]["data"] = mapping
|
2867
|
-
event_data["moved"]["rows"]["displayed"] = disp_mapping
|
2868
2837
|
|
2869
2838
|
return event_data
|
2870
2839
|
|
@@ -2872,21 +2841,11 @@ class RowIndex(tk.Canvas):
|
|
2872
2841
|
for iid, node in event_data["treeview"]["nodes"].items():
|
2873
2842
|
self.MT._row_index[self.rns[iid]] = node
|
2874
2843
|
|
2875
|
-
def copy_node(self, item: str) -> Node:
|
2876
|
-
n = self.iid_node(item)
|
2877
|
-
return Node(
|
2878
|
-
text=n.text,
|
2879
|
-
iid=n.iid,
|
2880
|
-
parent=n.parent,
|
2881
|
-
children=n.children.copy(),
|
2882
|
-
)
|
2883
|
-
|
2884
2844
|
def copy_nodes(self, items: Iterator[str], event_data: EventDataDict) -> EventDataDict:
|
2885
|
-
nodes = event_data["treeview"]["nodes"]
|
2886
2845
|
for iid in items:
|
2887
|
-
if iid not in nodes:
|
2846
|
+
if iid not in event_data["treeview"]["nodes"]:
|
2888
2847
|
n = self.iid_node(iid)
|
2889
|
-
nodes[iid] = Node(
|
2848
|
+
event_data["treeview"]["nodes"][iid] = Node(
|
2890
2849
|
text=n.text,
|
2891
2850
|
iid=n.iid,
|
2892
2851
|
parent=n.parent,
|
@@ -4744,26 +4744,31 @@ class Sheet(tk.Frame):
|
|
4744
4744
|
self.hide_rows(datarn, deselect_all=False, data_indexes=True)
|
4745
4745
|
return iid
|
4746
4746
|
|
4747
|
-
def _get_id_insert_row(self, index: int, parent: str) -> int:
|
4747
|
+
def _get_id_insert_row(self, index: int | None, parent: str) -> int:
|
4748
4748
|
if parent:
|
4749
|
+
chn = self.RI.iid_children(parent)
|
4749
4750
|
if isinstance(index, int):
|
4750
|
-
index = min(index, len(
|
4751
|
-
|
4752
|
-
self.RI.rns[parent]
|
4753
|
-
|
4754
|
-
|
4755
|
-
|
4756
|
-
)
|
4751
|
+
index = min(index, len(chn))
|
4752
|
+
if index == 0:
|
4753
|
+
return self.RI.rns[parent] + 1
|
4754
|
+
else:
|
4755
|
+
prev_chld = chn[index - 1]
|
4756
|
+
return self.RI.rns[prev_chld] + self.RI.num_descendants(prev_chld) + 1
|
4757
4757
|
else:
|
4758
|
-
|
4758
|
+
if chn:
|
4759
|
+
last_chld = chn[-1]
|
4760
|
+
last_chld_rn = self.RI.rns[last_chld]
|
4761
|
+
return last_chld_rn + self.RI.num_descendants(last_chld) + 1
|
4762
|
+
else:
|
4763
|
+
return self.RI.rns[parent] + 1
|
4759
4764
|
else:
|
4760
4765
|
if isinstance(index, int):
|
4761
|
-
|
4762
|
-
|
4763
|
-
|
4766
|
+
if index == 0:
|
4767
|
+
return 0
|
4768
|
+
datarn = self.top_index_row(index)
|
4769
|
+
return len(self.MT._row_index) if datarn is None else datarn
|
4764
4770
|
else:
|
4765
|
-
|
4766
|
-
return datarn
|
4771
|
+
return len(self.MT._row_index)
|
4767
4772
|
|
4768
4773
|
def bulk_insert(
|
4769
4774
|
self,
|
@@ -4792,6 +4797,8 @@ class Sheet(tk.Frame):
|
|
4792
4797
|
rns_to_add = {}
|
4793
4798
|
for rn, r in enumerate(data, start=datarn):
|
4794
4799
|
iid = self.RI.new_iid() if iid_column is None else r[iid_column]
|
4800
|
+
if iid in self.RI.rns:
|
4801
|
+
raise ValueError(f"iid '{iid}' already exists.")
|
4795
4802
|
new_node = Node(
|
4796
4803
|
r[text_column] if isinstance(text_column, int) else text_column if isinstance(text_column, str) else "",
|
4797
4804
|
iid,
|
@@ -4995,11 +5002,24 @@ class Sheet(tk.Frame):
|
|
4995
5002
|
raise ValueError(f"Item '{item}' does not exist.")
|
4996
5003
|
return self.RI.iid_parent(item)
|
4997
5004
|
|
4998
|
-
def index(self, item: str) -> int:
|
5005
|
+
def index(self, item: str, safety: bool = False) -> int:
|
5006
|
+
"""
|
5007
|
+
Finds the index of an item amongst it's siblings in the
|
5008
|
+
treeview.
|
5009
|
+
|
5010
|
+
'safety' is only necessary when the internal row number dict
|
5011
|
+
is not able to provide row numbers, e.g. when modifying the
|
5012
|
+
tree and before the action is complete.
|
5013
|
+
|
5014
|
+
When 'True' the fn uses list.index() instead.
|
5015
|
+
"""
|
4999
5016
|
if item not in self.RI.rns:
|
5000
5017
|
raise ValueError(f"Item '{item}' does not exist.")
|
5001
|
-
elif self.RI.iid_parent(item):
|
5002
|
-
|
5018
|
+
elif par := self.RI.iid_parent(item):
|
5019
|
+
if not safety:
|
5020
|
+
return self.RI.rns[item] - self.RI.rns[par] - 1
|
5021
|
+
else:
|
5022
|
+
return self.RI.parent_node(item).children.index(item)
|
5003
5023
|
else:
|
5004
5024
|
return next(index for index, iid in enumerate(self.get_children("")) if iid == item)
|
5005
5025
|
|
@@ -6349,20 +6369,14 @@ class Sheet(tk.Frame):
|
|
6349
6369
|
**{k: v["dropdown"] for k, v in self.MT.row_options.items() if "dropdown" in v},
|
6350
6370
|
**{k: v["dropdown"] for k, v in self.MT.col_options.items() if "dropdown" in v},
|
6351
6371
|
}
|
6352
|
-
if "dropdown" in self.MT.options:
|
6353
|
-
return {**d, "dropdown": self.MT.options["dropdown"]}
|
6354
6372
|
return d
|
6355
6373
|
|
6356
6374
|
def get_header_dropdowns(self) -> dict:
|
6357
6375
|
d = {k: v["dropdown"] for k, v in self.CH.cell_options.items() if "dropdown" in v}
|
6358
|
-
if "dropdown" in self.CH.options:
|
6359
|
-
return {**d, "dropdown": self.CH.options["dropdown"]}
|
6360
6376
|
return d
|
6361
6377
|
|
6362
6378
|
def get_index_dropdowns(self) -> dict:
|
6363
6379
|
d = {k: v["dropdown"] for k, v in self.RI.cell_options.items() if "dropdown" in v}
|
6364
|
-
if "dropdown" in self.RI.options:
|
6365
|
-
return {**d, "dropdown": self.RI.options["dropdown"]}
|
6366
6380
|
return d
|
6367
6381
|
|
6368
6382
|
def set_dropdown_values(
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|