tksheet 7.5.3__tar.gz → 7.5.4__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.4}/PKG-INFO +1 -1
- {tksheet-7.5.3 → tksheet-7.5.4}/pyproject.toml +1 -1
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/__init__.py +1 -1
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/functions.py +0 -12
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/main_table.py +4 -6
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/other_classes.py +4 -4
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/row_index.py +33 -79
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/sheet.py +20 -11
- {tksheet-7.5.3 → tksheet-7.5.4/tksheet.egg-info}/PKG-INFO +1 -1
- {tksheet-7.5.3 → tksheet-7.5.4}/LICENSE.txt +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/README.md +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/setup.cfg +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/colors.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/column_headers.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/constants.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/find_window.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/formatters.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/sheet_options.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/sorting.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/text_editor.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/themes.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/tksheet_types.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/top_left_rectangle.py +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.5.3 → tksheet-7.5.4}/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.4"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -853,18 +853,6 @@ def insert_items(
|
|
853
853
|
return seq
|
854
854
|
|
855
855
|
|
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
856
|
def data_to_displayed_idxs(
|
869
857
|
to_convert: list[int],
|
870
858
|
displayed: list[int],
|
@@ -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,
|
@@ -839,7 +837,7 @@ class RowIndex(tk.Canvas):
|
|
839
837
|
move_heights=self.ops.row_drag_and_drop_perform,
|
840
838
|
event_data=event_data,
|
841
839
|
)
|
842
|
-
if data_new_idxs
|
840
|
+
if data_new_idxs:
|
843
841
|
event_data["moved"]["rows"] = {
|
844
842
|
"data": data_new_idxs,
|
845
843
|
"displayed": disp_new_idxs,
|
@@ -2675,34 +2673,38 @@ class RowIndex(tk.Canvas):
|
|
2675
2673
|
moved_rows = [self.rns[item]]
|
2676
2674
|
new_parent = node_change[1]
|
2677
2675
|
move_to_index = node_change[2]
|
2676
|
+
# new parent exists
|
2678
2677
|
if new_parent:
|
2678
|
+
new_par_cn = self.iid_children(new_parent)
|
2679
|
+
# determine index
|
2679
2680
|
if isinstance(move_to_index, int):
|
2680
|
-
move_to_index = min(move_to_index, len(
|
2681
|
+
move_to_index = min(move_to_index, len(new_par_cn))
|
2681
2682
|
else:
|
2682
|
-
move_to_index = len(
|
2683
|
-
|
2684
|
-
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2683
|
+
move_to_index = len(new_par_cn)
|
2684
|
+
# determine insert row
|
2685
|
+
if not new_par_cn:
|
2686
|
+
insert_row = self.rns[new_parent] + 1
|
2687
|
+
elif move_to_index >= len(new_par_cn):
|
2688
|
+
insert_row = self.rns[new_par_cn[-1]] + self.num_descendants(new_par_cn[-1]) + 1
|
2689
|
+
elif new_parent == self.iid_parent(item):
|
2690
|
+
if move_to_index <= self.PAR.index(item):
|
2691
|
+
# Insert before the sibling at move_to_index
|
2692
|
+
insert_row = self.rns[new_par_cn[move_to_index]]
|
2693
|
+
else:
|
2694
|
+
# Insert after the sibling at move_to_index
|
2695
|
+
insert_row = self.rns[new_par_cn[move_to_index]]
|
2696
|
+
insert_row += 1 + self.num_descendants(new_par_cn[move_to_index])
|
2697
|
+
else:
|
2698
|
+
insert_row = self.rns[new_par_cn[move_to_index]]
|
2699
|
+
# no new parent
|
2689
2700
|
else:
|
2690
|
-
|
2691
|
-
if move_to_index
|
2692
|
-
|
2693
|
-
move_to_index = num_top_nodes
|
2694
|
-
insert_row = move_to_row
|
2701
|
+
# determine index
|
2702
|
+
if isinstance(move_to_index, int):
|
2703
|
+
move_to_index = min(move_to_index, sum(1 for _ in self.gen_top_nodes()))
|
2695
2704
|
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
|
-
|
2705
|
+
move_to_index = sum(1 for _ in self.gen_top_nodes())
|
2706
|
+
# determine insert row
|
2707
|
+
insert_row = self.PAR._get_id_insert_row(move_to_index, new_parent)
|
2706
2708
|
else:
|
2707
2709
|
iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
|
2708
2710
|
iids_descendants = {iid: set(self.get_iid_descendants(iid)) for iid in iids}
|
@@ -2713,21 +2715,18 @@ class RowIndex(tk.Canvas):
|
|
2713
2715
|
item = self.MT._row_index[moved_rows[0]].iid
|
2714
2716
|
|
2715
2717
|
if isinstance(event_data.value, int):
|
2716
|
-
|
2717
|
-
if disp_insert_row >= len(self.MT.displayed_rows):
|
2718
|
+
if event_data.value >= len(self.MT.displayed_rows):
|
2718
2719
|
insert_row = len(self.MT._row_index)
|
2719
2720
|
else:
|
2720
|
-
insert_row = self.MT.datarn(
|
2721
|
+
insert_row = self.MT.datarn(event_data.value)
|
2721
2722
|
move_to_iid = self.MT._row_index[min(insert_row, len(self.MT._row_index) - 1)].iid
|
2722
2723
|
|
2723
2724
|
else:
|
2724
|
-
disp_insert_row = None
|
2725
2725
|
min_from = min(event_data["moved"]["rows"]["data"])
|
2726
2726
|
# max_from = max(event_data.moved.rows)
|
2727
2727
|
min_to = min(event_data["moved"]["rows"]["data"].values())
|
2728
2728
|
max_to = max(event_data["moved"]["rows"]["data"].values())
|
2729
2729
|
insert_row = max_to if min_from <= min_to else min_to
|
2730
|
-
move_to_row = insert_row
|
2731
2730
|
move_to_iid = self.MT._row_index[insert_row].iid
|
2732
2731
|
|
2733
2732
|
move_to_index = self.PAR.index(move_to_iid)
|
@@ -2738,19 +2737,7 @@ class RowIndex(tk.Canvas):
|
|
2738
2737
|
new_loc_is_displayed = not new_parent or (
|
2739
2738
|
new_parent and new_parent in self.tree_open_ids and self.PAR.item_displayed(new_parent)
|
2740
2739
|
)
|
2741
|
-
# deal with displayed mapping
|
2742
2740
|
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
2741
|
|
2755
2742
|
if any(self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows):
|
2756
2743
|
event_data["moved"]["rows"] = {}
|
@@ -2772,15 +2759,6 @@ class RowIndex(tk.Canvas):
|
|
2772
2759
|
)
|
2773
2760
|
data_new_idxs = event_data["moved"]["rows"]["data"]
|
2774
2761
|
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
2762
|
disp_new_idxs = event_data["moved"]["rows"]["displayed"]
|
2785
2763
|
|
2786
2764
|
if data_new_idxs:
|
@@ -2817,8 +2795,7 @@ class RowIndex(tk.Canvas):
|
|
2817
2795
|
# its the same parent, we're just moving index
|
2818
2796
|
if parent == item_node.parent:
|
2819
2797
|
event_data = self.copy_nodes((item, parent), event_data)
|
2820
|
-
|
2821
|
-
parent_node.children.insert(index, parent_node.children.pop(pop_index))
|
2798
|
+
parent_node.children.insert(index, parent_node.children.pop(parent_node.children.index(item)))
|
2822
2799
|
|
2823
2800
|
else:
|
2824
2801
|
if item_node.parent:
|
@@ -2842,29 +2819,16 @@ class RowIndex(tk.Canvas):
|
|
2842
2819
|
mapping = event_data["moved"]["rows"]["data"]
|
2843
2820
|
row_ctr = next(reversed(mapping.values())) + 1
|
2844
2821
|
|
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
2822
|
rn = self.rns[item]
|
2852
2823
|
if rn not in mapping:
|
2853
2824
|
mapping[rn] = row_ctr
|
2854
2825
|
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
2826
|
|
2859
2827
|
for did in self.get_iid_descendants(item):
|
2860
2828
|
mapping[self.rns[did]] = row_ctr
|
2861
2829
|
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
2830
|
|
2866
2831
|
event_data["moved"]["rows"]["data"] = mapping
|
2867
|
-
event_data["moved"]["rows"]["displayed"] = disp_mapping
|
2868
2832
|
|
2869
2833
|
return event_data
|
2870
2834
|
|
@@ -2872,21 +2836,11 @@ class RowIndex(tk.Canvas):
|
|
2872
2836
|
for iid, node in event_data["treeview"]["nodes"].items():
|
2873
2837
|
self.MT._row_index[self.rns[iid]] = node
|
2874
2838
|
|
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
2839
|
def copy_nodes(self, items: Iterator[str], event_data: EventDataDict) -> EventDataDict:
|
2885
|
-
nodes = event_data["treeview"]["nodes"]
|
2886
2840
|
for iid in items:
|
2887
|
-
if iid not in nodes:
|
2841
|
+
if iid not in event_data["treeview"]["nodes"]:
|
2888
2842
|
n = self.iid_node(iid)
|
2889
|
-
nodes[iid] = Node(
|
2843
|
+
event_data["treeview"]["nodes"][iid] = Node(
|
2890
2844
|
text=n.text,
|
2891
2845
|
iid=n.iid,
|
2892
2846
|
parent=n.parent,
|
@@ -4744,7 +4744,7 @@ 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
4749
|
if isinstance(index, int):
|
4750
4750
|
index = min(index, len(self.RI.iid_children(parent)))
|
@@ -4759,7 +4759,7 @@ class Sheet(tk.Frame):
|
|
4759
4759
|
else:
|
4760
4760
|
if isinstance(index, int):
|
4761
4761
|
datarn = index
|
4762
|
-
if index and (datarn := self.top_index_row(
|
4762
|
+
if index and (datarn := self.top_index_row(index)) is None:
|
4763
4763
|
datarn = len(self.MT._row_index)
|
4764
4764
|
else:
|
4765
4765
|
datarn = len(self.MT._row_index)
|
@@ -4792,6 +4792,8 @@ class Sheet(tk.Frame):
|
|
4792
4792
|
rns_to_add = {}
|
4793
4793
|
for rn, r in enumerate(data, start=datarn):
|
4794
4794
|
iid = self.RI.new_iid() if iid_column is None else r[iid_column]
|
4795
|
+
if iid in self.RI.rns:
|
4796
|
+
raise ValueError(f"iid '{iid}' already exists.")
|
4795
4797
|
new_node = Node(
|
4796
4798
|
r[text_column] if isinstance(text_column, int) else text_column if isinstance(text_column, str) else "",
|
4797
4799
|
iid,
|
@@ -4995,11 +4997,24 @@ class Sheet(tk.Frame):
|
|
4995
4997
|
raise ValueError(f"Item '{item}' does not exist.")
|
4996
4998
|
return self.RI.iid_parent(item)
|
4997
4999
|
|
4998
|
-
def index(self, item: str) -> int:
|
5000
|
+
def index(self, item: str, safety: bool = False) -> int:
|
5001
|
+
"""
|
5002
|
+
Finds the index of an item amongst it's siblings in the
|
5003
|
+
treeview.
|
5004
|
+
|
5005
|
+
'safety' is only necessary when the internal row number dict
|
5006
|
+
is not able to provide row numbers, e.g. when modifying the
|
5007
|
+
tree and before the action is complete.
|
5008
|
+
|
5009
|
+
When 'True' the fn uses list.index() instead.
|
5010
|
+
"""
|
4999
5011
|
if item not in self.RI.rns:
|
5000
5012
|
raise ValueError(f"Item '{item}' does not exist.")
|
5001
|
-
elif self.RI.iid_parent(item):
|
5002
|
-
|
5013
|
+
elif par := self.RI.iid_parent(item):
|
5014
|
+
if not safety:
|
5015
|
+
return self.RI.rns[item] - self.RI.rns[par] - 1
|
5016
|
+
else:
|
5017
|
+
return self.RI.parent_node(item).children.index(item)
|
5003
5018
|
else:
|
5004
5019
|
return next(index for index, iid in enumerate(self.get_children("")) if iid == item)
|
5005
5020
|
|
@@ -6349,20 +6364,14 @@ class Sheet(tk.Frame):
|
|
6349
6364
|
**{k: v["dropdown"] for k, v in self.MT.row_options.items() if "dropdown" in v},
|
6350
6365
|
**{k: v["dropdown"] for k, v in self.MT.col_options.items() if "dropdown" in v},
|
6351
6366
|
}
|
6352
|
-
if "dropdown" in self.MT.options:
|
6353
|
-
return {**d, "dropdown": self.MT.options["dropdown"]}
|
6354
6367
|
return d
|
6355
6368
|
|
6356
6369
|
def get_header_dropdowns(self) -> dict:
|
6357
6370
|
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
6371
|
return d
|
6361
6372
|
|
6362
6373
|
def get_index_dropdowns(self) -> dict:
|
6363
6374
|
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
6375
|
return d
|
6367
6376
|
|
6368
6377
|
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
|