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/sheet.py
CHANGED
@@ -4,6 +4,7 @@ import tkinter as tk
|
|
4
4
|
from bisect import bisect_left
|
5
5
|
from collections import deque
|
6
6
|
from collections.abc import Callable, Generator, Hashable, Iterator, Sequence
|
7
|
+
from contextlib import suppress
|
7
8
|
from itertools import accumulate, chain, filterfalse, islice, product, repeat
|
8
9
|
from operator import attrgetter
|
9
10
|
from timeit import default_timer
|
@@ -54,6 +55,7 @@ from .functions import (
|
|
54
55
|
)
|
55
56
|
from .main_table import MainTable
|
56
57
|
from .other_classes import (
|
58
|
+
Box_nt,
|
57
59
|
DotDict,
|
58
60
|
EventDataDict,
|
59
61
|
FontTuple,
|
@@ -66,6 +68,7 @@ from .other_classes import (
|
|
66
68
|
)
|
67
69
|
from .row_index import RowIndex
|
68
70
|
from .sheet_options import new_sheet_options
|
71
|
+
from .sorting import fast_sort_key, natural_sort_key, version_sort_key # noqa: F401
|
69
72
|
from .themes import (
|
70
73
|
theme_black,
|
71
74
|
theme_dark,
|
@@ -121,14 +124,14 @@ class Sheet(tk.Frame):
|
|
121
124
|
header_align: str = "n",
|
122
125
|
row_index_align: str | None = None,
|
123
126
|
index_align: str = "n",
|
124
|
-
displayed_columns: list[int] =
|
127
|
+
displayed_columns: list[int] | None = None,
|
125
128
|
all_columns_displayed: bool = True,
|
126
|
-
displayed_rows: list[int] =
|
129
|
+
displayed_rows: list[int] | None = None,
|
127
130
|
all_rows_displayed: bool = True,
|
128
131
|
to_clipboard_delimiter: str = "\t",
|
129
132
|
to_clipboard_quotechar: str = '"',
|
130
133
|
to_clipboard_lineterminator: str = "\n",
|
131
|
-
from_clipboard_delimiters: list[str] | str =
|
134
|
+
from_clipboard_delimiters: list[str] | str = "\t",
|
132
135
|
show_default_header_for_empty: bool = True,
|
133
136
|
show_default_index_for_empty: bool = True,
|
134
137
|
page_up_down_select_row: bool = True,
|
@@ -187,6 +190,7 @@ class Sheet(tk.Frame):
|
|
187
190
|
table_wrap: Literal["", "w", "c"] = "c",
|
188
191
|
index_wrap: Literal["", "w", "c"] = "c",
|
189
192
|
header_wrap: Literal["", "w", "c"] = "c",
|
193
|
+
sort_key: Callable = natural_sort_key,
|
190
194
|
# colors
|
191
195
|
outline_thickness: int = 0,
|
192
196
|
theme: str = "light blue",
|
@@ -731,10 +735,14 @@ class Sheet(tk.Frame):
|
|
731
735
|
- "rc_delete_row", "end_rc_delete_row", "end_delete_rows", "delete_rows"
|
732
736
|
- "begin_rc_delete_column", "begin_delete_columns"
|
733
737
|
- "rc_delete_column", "end_rc_delete_column","end_delete_columns", "delete_columns"
|
734
|
-
- "begin_rc_insert_column", "begin_insert_column", "begin_insert_columns", "begin_add_column",
|
735
|
-
|
736
|
-
- "
|
737
|
-
|
738
|
+
- "begin_rc_insert_column", "begin_insert_column", "begin_insert_columns", "begin_add_column",
|
739
|
+
"begin_rc_add_column", "begin_add_columns"
|
740
|
+
- "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column",
|
741
|
+
"end_rc_add_column", "end_add_column", "end_add_columns", "add_columns"
|
742
|
+
- "begin_rc_insert_row", "begin_insert_row", "begin_insert_rows", "begin_rc_add_row", "begin_add_row",
|
743
|
+
"begin_add_rows"
|
744
|
+
- "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row",
|
745
|
+
"end_add_row", "end_add_rows", "add_rows"
|
738
746
|
- "row_height_resize"
|
739
747
|
- "column_width_resize"
|
740
748
|
- "cell_select"
|
@@ -1610,10 +1618,7 @@ class Sheet(tk.Frame):
|
|
1610
1618
|
res = list(chain.from_iterable(res))
|
1611
1619
|
elif span.ndim == 1:
|
1612
1620
|
# flatten sublists
|
1613
|
-
if len(res) == 1 and len(res[0]) == 1
|
1614
|
-
res = res[0]
|
1615
|
-
else:
|
1616
|
-
res = list(chain.from_iterable(res))
|
1621
|
+
res = res[0] if len(res) == 1 and len(res[0]) == 1 else list(chain.from_iterable(res))
|
1617
1622
|
# if span.ndim == 2 res keeps its current
|
1618
1623
|
# dimensions as a list of lists
|
1619
1624
|
if span.convert is not None:
|
@@ -2205,10 +2210,7 @@ class Sheet(tk.Frame):
|
|
2205
2210
|
c_ops=False,
|
2206
2211
|
)
|
2207
2212
|
numrows = len(data)
|
2208
|
-
if self.MT.all_rows_displayed
|
2209
|
-
displayed_ins_idx = idx
|
2210
|
-
else:
|
2211
|
-
displayed_ins_idx = bisect_left(self.MT.displayed_rows, idx)
|
2213
|
+
displayed_ins_idx = idx if self.MT.all_rows_displayed else bisect_left(self.MT.displayed_rows, idx)
|
2212
2214
|
event_data = self.MT.add_rows(
|
2213
2215
|
*self.MT.get_args_for_add_rows(
|
2214
2216
|
data_ins_row=idx,
|
@@ -2586,7 +2588,7 @@ class Sheet(tk.Frame):
|
|
2586
2588
|
|
2587
2589
|
def sort(
|
2588
2590
|
self,
|
2589
|
-
|
2591
|
+
*box: CreateSpanTypes,
|
2590
2592
|
reverse: bool = False,
|
2591
2593
|
row_wise: bool = False,
|
2592
2594
|
validation: bool = True,
|
@@ -2596,20 +2598,15 @@ class Sheet(tk.Frame):
|
|
2596
2598
|
"""
|
2597
2599
|
Sort the data within specified box regions in the table.
|
2598
2600
|
|
2599
|
-
This method sorts the data within one or multiple box regions defined by their coordinates.
|
2601
|
+
This method sorts the data within one or multiple box regions defined by their coordinates.
|
2602
|
+
Each box's columns are sorted independently.
|
2600
2603
|
|
2601
2604
|
Args:
|
2602
|
-
boxes (
|
2603
|
-
- From Row (inclusive)
|
2604
|
-
- From Column (inclusive)
|
2605
|
-
- Up To Row (exclusive)
|
2606
|
-
- Up To Column (exclusive)
|
2607
|
-
If None, it will sort the currently selected boxes or the entire table.
|
2608
|
-
If Span, it will use the span coordinates.
|
2605
|
+
boxes (CreateSpanTypes): A type that can create a Span.
|
2609
2606
|
|
2610
2607
|
reverse (bool): If True, sorts in descending order. Default is False (ascending).
|
2611
2608
|
|
2612
|
-
row_wise (bool): if True sorts cells row-wise. Default is column-wise
|
2609
|
+
row_wise (bool): if True sorts cells row-wise. Default is column-wise.
|
2613
2610
|
|
2614
2611
|
validation (bool): If True, checks if the new cell values are valid according to any restrictions
|
2615
2612
|
(e.g., dropdown validations) before applying the sort. Default is True.
|
@@ -2620,25 +2617,28 @@ class Sheet(tk.Frame):
|
|
2620
2617
|
Note: Performance might be slow with the natural sort for very large datasets.
|
2621
2618
|
|
2622
2619
|
Returns:
|
2623
|
-
EventDataDict: A dictionary containing information about the sorting event,
|
2620
|
+
EventDataDict: A dictionary containing information about the sorting event,
|
2621
|
+
including changes made to the table.
|
2624
2622
|
|
2625
2623
|
Raises:
|
2626
2624
|
ValueError: If the input boxes are not in the expected format or if the data cannot be sorted.
|
2627
2625
|
|
2628
2626
|
Note:
|
2629
|
-
- Sorting is performed column-wise within each box.
|
2630
2627
|
- If validation is enabled, any cell content that fails validation will not be updated.
|
2631
2628
|
- Any cell options attached to cells will not be moved. Event data can be used to re-locate them.
|
2632
2629
|
"""
|
2633
|
-
if isinstance(boxes, Span):
|
2634
|
-
boxes = [boxes.coords]
|
2635
2630
|
return self.MT.sort_boxes(
|
2636
|
-
boxes=
|
2631
|
+
boxes={Box_nt(*self.span_from_key(*box).coords): "cells"},
|
2632
|
+
reverse=reverse,
|
2633
|
+
row_wise=row_wise,
|
2634
|
+
validation=validation,
|
2635
|
+
key=key,
|
2636
|
+
undo=undo,
|
2637
2637
|
)
|
2638
2638
|
|
2639
2639
|
def sort_rows(
|
2640
2640
|
self,
|
2641
|
-
rows: AnyIter[int] | Span | None = None,
|
2641
|
+
rows: AnyIter[int] | Span | int | None = None,
|
2642
2642
|
reverse: bool = False,
|
2643
2643
|
validation: bool = True,
|
2644
2644
|
key: Callable | None = None,
|
@@ -2646,11 +2646,13 @@ class Sheet(tk.Frame):
|
|
2646
2646
|
) -> EventDataDict:
|
2647
2647
|
if isinstance(rows, Span):
|
2648
2648
|
rows = rows.rows
|
2649
|
+
elif isinstance(rows, int):
|
2650
|
+
rows = (rows,)
|
2649
2651
|
return self.RI._sort_rows(rows=rows, reverse=reverse, validation=validation, key=key, undo=undo)
|
2650
2652
|
|
2651
2653
|
def sort_columns(
|
2652
2654
|
self,
|
2653
|
-
columns: AnyIter[int] | Span | None = None,
|
2655
|
+
columns: AnyIter[int] | Span | int | None = None,
|
2654
2656
|
reverse: bool = False,
|
2655
2657
|
validation: bool = True,
|
2656
2658
|
key: Callable | None = None,
|
@@ -2658,6 +2660,8 @@ class Sheet(tk.Frame):
|
|
2658
2660
|
) -> EventDataDict:
|
2659
2661
|
if isinstance(columns, Span):
|
2660
2662
|
columns = columns.columns
|
2663
|
+
elif isinstance(columns, int):
|
2664
|
+
columns = (columns,)
|
2661
2665
|
return self.CH._sort_columns(columns=columns, reverse=reverse, validation=validation, key=key, undo=undo)
|
2662
2666
|
|
2663
2667
|
def sort_rows_by_column(
|
@@ -2755,9 +2759,9 @@ class Sheet(tk.Frame):
|
|
2755
2759
|
def dropdown(
|
2756
2760
|
self,
|
2757
2761
|
*key: CreateSpanTypes,
|
2758
|
-
values: list =
|
2762
|
+
values: list[object] | None = None,
|
2759
2763
|
edit_data: bool = True,
|
2760
|
-
set_values: dict[tuple[int, int], object] =
|
2764
|
+
set_values: dict[tuple[int, int], object] | None = None,
|
2761
2765
|
set_value: object = None,
|
2762
2766
|
state: Literal["normal", "readonly", "disabled"] = "normal",
|
2763
2767
|
redraw: bool = True,
|
@@ -2767,6 +2771,10 @@ class Sheet(tk.Frame):
|
|
2767
2771
|
validate_input: bool = True,
|
2768
2772
|
text: None | str = None,
|
2769
2773
|
) -> Span:
|
2774
|
+
if values is None:
|
2775
|
+
values = []
|
2776
|
+
if set_values is None:
|
2777
|
+
set_values = {}
|
2770
2778
|
if not search_function:
|
2771
2779
|
search_function = dropdown_search_function
|
2772
2780
|
v = set_value if set_value is not None else values[0] if values else ""
|
@@ -2791,13 +2799,13 @@ class Sheet(tk.Frame):
|
|
2791
2799
|
self.del_index_cell_options_dropdown_and_checkbox(r)
|
2792
2800
|
add_to_options(self.RI.cell_options, r, "dropdown", d)
|
2793
2801
|
if edit_data:
|
2794
|
-
set_idata(r, value=set_values
|
2802
|
+
set_idata(r, value=set_values.get(r, v))
|
2795
2803
|
if header:
|
2796
2804
|
for c in cols:
|
2797
2805
|
self.del_header_cell_options_dropdown_and_checkbox(c)
|
2798
2806
|
add_to_options(self.CH.cell_options, c, "dropdown", d)
|
2799
2807
|
if edit_data:
|
2800
|
-
set_hdata(c, value=set_values
|
2808
|
+
set_hdata(c, value=set_values.get(c, v))
|
2801
2809
|
if table:
|
2802
2810
|
if span.kind == "cell":
|
2803
2811
|
for r in rows:
|
@@ -2805,21 +2813,21 @@ class Sheet(tk.Frame):
|
|
2805
2813
|
self.del_cell_options_dropdown_and_checkbox(r, c)
|
2806
2814
|
add_to_options(self.MT.cell_options, (r, c), "dropdown", d)
|
2807
2815
|
if edit_data:
|
2808
|
-
set_tdata(r, c, value=set_values
|
2816
|
+
set_tdata(r, c, value=set_values.get((r, c), v))
|
2809
2817
|
elif span.kind == "row":
|
2810
2818
|
for r in rows:
|
2811
2819
|
self.del_row_options_dropdown_and_checkbox(r)
|
2812
2820
|
add_to_options(self.MT.row_options, r, "dropdown", d)
|
2813
2821
|
if edit_data:
|
2814
2822
|
for c in cols:
|
2815
|
-
set_tdata(r, c, value=set_values
|
2823
|
+
set_tdata(r, c, value=set_values.get((r, c), v))
|
2816
2824
|
elif span.kind == "column":
|
2817
2825
|
for c in cols:
|
2818
2826
|
self.del_column_options_dropdown_and_checkbox(c)
|
2819
2827
|
add_to_options(self.MT.col_options, c, "dropdown", d)
|
2820
2828
|
if edit_data:
|
2821
2829
|
for r in rows:
|
2822
|
-
set_tdata(r, c, value=set_values
|
2830
|
+
set_tdata(r, c, value=set_values.get((r, c), v))
|
2823
2831
|
self.set_refresh_timer(redraw)
|
2824
2832
|
return span
|
2825
2833
|
|
@@ -2999,11 +3007,13 @@ class Sheet(tk.Frame):
|
|
2999
3007
|
def format(
|
3000
3008
|
self,
|
3001
3009
|
*key: CreateSpanTypes,
|
3002
|
-
formatter_options: dict =
|
3010
|
+
formatter_options: dict | None = None,
|
3003
3011
|
formatter_class: object = None,
|
3004
3012
|
redraw: bool = True,
|
3005
3013
|
**kwargs,
|
3006
3014
|
) -> Span:
|
3015
|
+
if formatter_options is None:
|
3016
|
+
formatter_options = {}
|
3007
3017
|
span = self.span_from_key(*key)
|
3008
3018
|
rows, cols = self.ranges_from_span(span)
|
3009
3019
|
kwargs = fix_format_kwargs({"formatter": formatter_class, **formatter_options, **kwargs})
|
@@ -4031,7 +4041,7 @@ class Sheet(tk.Frame):
|
|
4031
4041
|
column: int = 0,
|
4032
4042
|
keep_yscroll: bool = False,
|
4033
4043
|
keep_xscroll: bool = False,
|
4034
|
-
bottom_right_corner: bool =
|
4044
|
+
bottom_right_corner: bool | None = None,
|
4035
4045
|
check_cell_visibility: bool = True,
|
4036
4046
|
redraw: bool = True,
|
4037
4047
|
) -> Sheet:
|
@@ -4050,7 +4060,11 @@ class Sheet(tk.Frame):
|
|
4050
4060
|
return self.MT.cell_visible(r, c)
|
4051
4061
|
|
4052
4062
|
def cell_completely_visible(self, r: int, c: int, seperate_axes: bool = False) -> bool:
|
4053
|
-
|
4063
|
+
if seperate_axes:
|
4064
|
+
d = self.MT.cell_visibility_info(r, c)
|
4065
|
+
return d["yvis"], d["xvis"]
|
4066
|
+
else:
|
4067
|
+
return self.MT.cell_completely_visible(r, c)
|
4054
4068
|
|
4055
4069
|
def set_xview(self, position: None | float = None, option: str = "moveto") -> Sheet | tuple[float, float]:
|
4056
4070
|
if position is not None:
|
@@ -4504,18 +4518,14 @@ class Sheet(tk.Frame):
|
|
4504
4518
|
def unbind_key_text_editor(self, key: str) -> Sheet:
|
4505
4519
|
if key == "all":
|
4506
4520
|
for key in self.MT.text_editor_user_bound_keys:
|
4507
|
-
|
4521
|
+
with suppress(Exception):
|
4508
4522
|
self.MT.text_editor.tktext.unbind(key)
|
4509
|
-
except Exception:
|
4510
|
-
pass
|
4511
4523
|
self.MT.text_editor_user_bound_keys = {}
|
4512
4524
|
else:
|
4513
4525
|
if key in self.MT.text_editor_user_bound_keys:
|
4514
4526
|
del self.MT.text_editor_user_bound_keys[key]
|
4515
|
-
|
4527
|
+
with suppress(Exception):
|
4516
4528
|
self.MT.text_editor.tktext.unbind(key)
|
4517
|
-
except Exception:
|
4518
|
-
pass
|
4519
4529
|
return self
|
4520
4530
|
|
4521
4531
|
def get_text_editor_value(self) -> str | None:
|
@@ -4662,24 +4672,14 @@ class Sheet(tk.Frame):
|
|
4662
4672
|
Also retrieves any row or column options
|
4663
4673
|
impacting that cell
|
4664
4674
|
"""
|
4665
|
-
|
4666
|
-
|
4667
|
-
|
4668
|
-
|
4669
|
-
|
4670
|
-
|
4671
|
-
|
4672
|
-
|
4673
|
-
row=rowops,
|
4674
|
-
column=columnops,
|
4675
|
-
)
|
4676
|
-
if cellops and (row, column) in self.MT.cell_options:
|
4677
|
-
return self.MT.cell_options[(row, column)]
|
4678
|
-
if rowops and row in self.MT.row_options:
|
4679
|
-
return self.MT.row_options[row]
|
4680
|
-
if columnops and column in self.MT.col_options:
|
4681
|
-
return self.MT.col_options[column]
|
4682
|
-
return {}
|
4675
|
+
return self.MT.get_cell_kwargs(
|
4676
|
+
datarn=row,
|
4677
|
+
datacn=alpha2idx(column) if isinstance(column, str) else column,
|
4678
|
+
key=key,
|
4679
|
+
cell=cellops,
|
4680
|
+
row=rowops,
|
4681
|
+
column=columnops,
|
4682
|
+
)
|
4683
4683
|
|
4684
4684
|
def index_props(
|
4685
4685
|
self,
|
@@ -4690,12 +4690,10 @@ class Sheet(tk.Frame):
|
|
4690
4690
|
Retrieve options (properties - props)
|
4691
4691
|
from a cell in the index
|
4692
4692
|
"""
|
4693
|
-
|
4694
|
-
|
4695
|
-
|
4696
|
-
|
4697
|
-
)
|
4698
|
-
return self.RI.cell_options[row] if row in self.RI.cell_options else {}
|
4693
|
+
return self.RI.get_cell_kwargs(
|
4694
|
+
datarn=row,
|
4695
|
+
key=key,
|
4696
|
+
)
|
4699
4697
|
|
4700
4698
|
def header_props(
|
4701
4699
|
self,
|
@@ -4706,14 +4704,10 @@ class Sheet(tk.Frame):
|
|
4706
4704
|
Retrieve options (properties - props)
|
4707
4705
|
from a cell in the header
|
4708
4706
|
"""
|
4709
|
-
|
4710
|
-
column
|
4711
|
-
|
4712
|
-
|
4713
|
-
datacn=column,
|
4714
|
-
key=key,
|
4715
|
-
)
|
4716
|
-
return self.CH.cell_options[column] if column in self.CH.cell_options else {}
|
4707
|
+
return self.CH.get_cell_kwargs(
|
4708
|
+
datacn=alpha2idx(column) if isinstance(column, str) else column,
|
4709
|
+
key=key,
|
4710
|
+
)
|
4717
4711
|
|
4718
4712
|
def get_cell_options(
|
4719
4713
|
self,
|
@@ -4990,9 +4984,9 @@ class Sheet(tk.Frame):
|
|
4990
4984
|
columns=set(),
|
4991
4985
|
)
|
4992
4986
|
for tag in unpack(tags):
|
4993
|
-
res.cells.update(self.MT.tagged_cells
|
4994
|
-
res.rows.update(self.MT.tagged_rows
|
4995
|
-
res.columns.update(self.MT.tagged_columns
|
4987
|
+
res.cells.update(self.MT.tagged_cells.get(tag, set()))
|
4988
|
+
res.rows.update(self.MT.tagged_rows.get(tag, set()))
|
4989
|
+
res.columns.update(self.MT.tagged_columns.get(tag, set()))
|
4996
4990
|
return res
|
4997
4991
|
|
4998
4992
|
# Treeview Mode
|
@@ -5086,10 +5080,7 @@ class Sheet(tk.Frame):
|
|
5086
5080
|
"""
|
5087
5081
|
If used without args all items are opened
|
5088
5082
|
"""
|
5089
|
-
if items := set(unpack(items))
|
5090
|
-
to_open = self._tree_open(items)
|
5091
|
-
else:
|
5092
|
-
to_open = self._tree_open(set(self.get_children()))
|
5083
|
+
to_open = self._tree_open(items) if (items := set(unpack(items))) else self._tree_open(set(self.get_children()))
|
5093
5084
|
return self.show_rows(
|
5094
5085
|
rows=to_open,
|
5095
5086
|
redraw=redraw,
|
@@ -5116,10 +5107,7 @@ class Sheet(tk.Frame):
|
|
5116
5107
|
"""
|
5117
5108
|
If used without args all items are closed
|
5118
5109
|
"""
|
5119
|
-
if items
|
5120
|
-
to_close = self._tree_close(unpack(items))
|
5121
|
-
else:
|
5122
|
-
to_close = self._tree_close(self.get_children())
|
5110
|
+
to_close = self._tree_close(unpack(items)) if items else self._tree_close(self.get_children())
|
5123
5111
|
return self.hide_rows(
|
5124
5112
|
rows=to_close,
|
5125
5113
|
redraw=redraw,
|
@@ -5177,13 +5165,10 @@ class Sheet(tk.Frame):
|
|
5177
5165
|
self.RI.tree_rns[parent]
|
5178
5166
|
+ index
|
5179
5167
|
+ 1
|
5180
|
-
+ sum(
|
5181
|
-
sum(1 for _ in self.RI.get_iid_descendants(cid))
|
5182
|
-
for cid in islice(self.get_children(parent), index)
|
5183
|
-
)
|
5168
|
+
+ sum(self.RI.num_descendants(cid) for cid in islice(self.get_children(parent), index))
|
5184
5169
|
)
|
5185
5170
|
else:
|
5186
|
-
datarn = self.RI.tree_rns[parent] +
|
5171
|
+
datarn = self.RI.tree_rns[parent] + self.RI.num_descendants(parent) + 1
|
5187
5172
|
else:
|
5188
5173
|
if isinstance(index, int):
|
5189
5174
|
datarn = index
|
@@ -5219,10 +5204,7 @@ class Sheet(tk.Frame):
|
|
5219
5204
|
datarn = self._get_id_insert_row(index=index, parent=parent)
|
5220
5205
|
rns_to_add = {}
|
5221
5206
|
for rn, r in enumerate(data, start=datarn):
|
5222
|
-
if iid_column is None
|
5223
|
-
iid = self.RI.new_iid()
|
5224
|
-
else:
|
5225
|
-
iid = r[iid_column]
|
5207
|
+
iid = self.RI.new_iid() if iid_column is None else r[iid_column]
|
5226
5208
|
new_node = Node(
|
5227
5209
|
r[text_column] if isinstance(text_column, int) else text_column if isinstance(text_column, str) else "",
|
5228
5210
|
iid,
|
@@ -5315,8 +5297,8 @@ class Sheet(tk.Frame):
|
|
5315
5297
|
def itemrow(self, item: str) -> int:
|
5316
5298
|
try:
|
5317
5299
|
return self.RI.tree_rns[item]
|
5318
|
-
except
|
5319
|
-
raise ValueError(f"item '{item}' does not exist.")
|
5300
|
+
except ValueError as error:
|
5301
|
+
raise ValueError(f"item '{item}' does not exist.") from error
|
5320
5302
|
|
5321
5303
|
def rowitem(self, row: int, data_index: bool = False) -> str | None:
|
5322
5304
|
try:
|
@@ -5537,7 +5519,7 @@ class Sheet(tk.Frame):
|
|
5537
5519
|
return self.set_refresh_timer(redraw)
|
5538
5520
|
|
5539
5521
|
def selection_toggle(self, *items, redraw: bool = True) -> Sheet:
|
5540
|
-
selected =
|
5522
|
+
selected = {self.MT._row_index[self.displayed_row_to_data(rn)].iid for rn in self.get_selected_rows()}
|
5541
5523
|
add = []
|
5542
5524
|
remove = []
|
5543
5525
|
for item in unpack(items):
|
@@ -5905,14 +5887,12 @@ class Sheet(tk.Frame):
|
|
5905
5887
|
|
5906
5888
|
def readonly_rows(
|
5907
5889
|
self,
|
5908
|
-
rows: list | int
|
5890
|
+
rows: list[int] | int,
|
5909
5891
|
readonly: bool = True,
|
5910
5892
|
redraw: bool = False,
|
5911
5893
|
) -> Sheet:
|
5912
5894
|
if isinstance(rows, int):
|
5913
5895
|
rows = [rows]
|
5914
|
-
else:
|
5915
|
-
rows = rows
|
5916
5896
|
if not readonly:
|
5917
5897
|
for r in rows:
|
5918
5898
|
if r in self.MT.row_options and "readonly" in self.MT.row_options[r]:
|
@@ -5926,14 +5906,12 @@ class Sheet(tk.Frame):
|
|
5926
5906
|
|
5927
5907
|
def readonly_columns(
|
5928
5908
|
self,
|
5929
|
-
columns: list | int
|
5909
|
+
columns: list[int] | int,
|
5930
5910
|
readonly: bool = True,
|
5931
5911
|
redraw: bool = False,
|
5932
5912
|
) -> Sheet:
|
5933
5913
|
if isinstance(columns, int):
|
5934
5914
|
columns = [columns]
|
5935
|
-
else:
|
5936
|
-
columns = columns
|
5937
5915
|
if not readonly:
|
5938
5916
|
for c in columns:
|
5939
5917
|
if c in self.MT.col_options and "readonly" in self.MT.col_options[c]:
|
@@ -5949,7 +5927,7 @@ class Sheet(tk.Frame):
|
|
5949
5927
|
self,
|
5950
5928
|
row: int = 0,
|
5951
5929
|
column: int = 0,
|
5952
|
-
cells: list =
|
5930
|
+
cells: list[tuple[int, int]] | None = None,
|
5953
5931
|
readonly: bool = True,
|
5954
5932
|
redraw: bool = False,
|
5955
5933
|
) -> Sheet:
|
@@ -5978,7 +5956,7 @@ class Sheet(tk.Frame):
|
|
5978
5956
|
|
5979
5957
|
def readonly_header(
|
5980
5958
|
self,
|
5981
|
-
columns: list
|
5959
|
+
columns: list[int],
|
5982
5960
|
readonly: bool = True,
|
5983
5961
|
redraw: bool = False,
|
5984
5962
|
) -> Sheet:
|
@@ -5987,7 +5965,7 @@ class Sheet(tk.Frame):
|
|
5987
5965
|
|
5988
5966
|
def readonly_index(
|
5989
5967
|
self,
|
5990
|
-
rows: list
|
5968
|
+
rows: list[int],
|
5991
5969
|
readonly: bool = True,
|
5992
5970
|
redraw: bool = False,
|
5993
5971
|
) -> Sheet:
|
@@ -5996,7 +5974,7 @@ class Sheet(tk.Frame):
|
|
5996
5974
|
|
5997
5975
|
def dehighlight_rows(
|
5998
5976
|
self,
|
5999
|
-
rows: list[int] | Literal["all"]
|
5977
|
+
rows: list[int] | Literal["all"],
|
6000
5978
|
redraw: bool = True,
|
6001
5979
|
) -> Sheet:
|
6002
5980
|
if isinstance(rows, int):
|
@@ -6011,19 +5989,15 @@ class Sheet(tk.Frame):
|
|
6011
5989
|
del self.RI.cell_options[r]["highlight"]
|
6012
5990
|
else:
|
6013
5991
|
for r in rows:
|
6014
|
-
|
5992
|
+
with suppress(Exception):
|
6015
5993
|
del self.MT.row_options[r]["highlight"]
|
6016
|
-
|
6017
|
-
pass
|
6018
|
-
try:
|
5994
|
+
with suppress(Exception):
|
6019
5995
|
del self.RI.cell_options[r]["highlight"]
|
6020
|
-
except Exception:
|
6021
|
-
pass
|
6022
5996
|
return self.set_refresh_timer(redraw)
|
6023
5997
|
|
6024
5998
|
def dehighlight_columns(
|
6025
5999
|
self,
|
6026
|
-
columns: list[int] | Literal["all"]
|
6000
|
+
columns: list[int] | Literal["all"],
|
6027
6001
|
redraw: bool = True,
|
6028
6002
|
) -> Sheet:
|
6029
6003
|
if isinstance(columns, int):
|
@@ -6038,14 +6012,10 @@ class Sheet(tk.Frame):
|
|
6038
6012
|
del self.CH.cell_options[c]["highlight"]
|
6039
6013
|
else:
|
6040
6014
|
for c in columns:
|
6041
|
-
|
6015
|
+
with suppress(Exception):
|
6042
6016
|
del self.MT.col_options[c]["highlight"]
|
6043
|
-
|
6044
|
-
pass
|
6045
|
-
try:
|
6017
|
+
with suppress(Exception):
|
6046
6018
|
del self.CH.cell_options[c]["highlight"]
|
6047
|
-
except Exception:
|
6048
|
-
pass
|
6049
6019
|
return self.set_refresh_timer(redraw)
|
6050
6020
|
|
6051
6021
|
def highlight_rows(
|
@@ -6087,7 +6057,7 @@ class Sheet(tk.Frame):
|
|
6087
6057
|
self,
|
6088
6058
|
row: int | Literal["all"] = 0,
|
6089
6059
|
column: int | Literal["all"] = 0,
|
6090
|
-
cells: list[tuple[int, int]] =
|
6060
|
+
cells: list[tuple[int, int]] | None = None,
|
6091
6061
|
canvas: Literal["table", "index", "header"] = "table",
|
6092
6062
|
bg: bool | None | str = False,
|
6093
6063
|
fg: bool | None | str = False,
|
@@ -6141,7 +6111,7 @@ class Sheet(tk.Frame):
|
|
6141
6111
|
self,
|
6142
6112
|
row: int | Literal["all"] = 0,
|
6143
6113
|
column: int = 0,
|
6144
|
-
cells: list[tuple[int, int]] =
|
6114
|
+
cells: list[tuple[int, int]] | None = None,
|
6145
6115
|
canvas: Literal["table", "row_index", "index", "header"] = "table",
|
6146
6116
|
all_: bool = False,
|
6147
6117
|
redraw: bool = True,
|
@@ -6220,7 +6190,7 @@ class Sheet(tk.Frame):
|
|
6220
6190
|
self,
|
6221
6191
|
row: int = 0,
|
6222
6192
|
column: int = 0,
|
6223
|
-
cells: list
|
6193
|
+
cells: list[tuple[int, int]] | dict[tuple[int, int], str] | None = None,
|
6224
6194
|
align: str | None = "global",
|
6225
6195
|
redraw: bool = True,
|
6226
6196
|
) -> Sheet:
|
@@ -6237,7 +6207,7 @@ class Sheet(tk.Frame):
|
|
6237
6207
|
|
6238
6208
|
def align_rows(
|
6239
6209
|
self,
|
6240
|
-
rows: list | dict | int
|
6210
|
+
rows: list[int] | dict[int, str] | int,
|
6241
6211
|
align: str | None = "global",
|
6242
6212
|
align_index: bool = False,
|
6243
6213
|
redraw: bool = True,
|
@@ -6262,7 +6232,7 @@ class Sheet(tk.Frame):
|
|
6262
6232
|
|
6263
6233
|
def align_columns(
|
6264
6234
|
self,
|
6265
|
-
columns: list | dict | int
|
6235
|
+
columns: list[int] | dict[int, str] | int,
|
6266
6236
|
align: str | None = "global",
|
6267
6237
|
align_header: bool = False,
|
6268
6238
|
redraw: bool = True,
|
@@ -6287,7 +6257,7 @@ class Sheet(tk.Frame):
|
|
6287
6257
|
|
6288
6258
|
def align_header(
|
6289
6259
|
self,
|
6290
|
-
columns: list | dict | int
|
6260
|
+
columns: list[int] | dict[int, str] | int,
|
6291
6261
|
align: str | None = "global",
|
6292
6262
|
redraw: bool = True,
|
6293
6263
|
) -> Sheet:
|
@@ -6304,7 +6274,7 @@ class Sheet(tk.Frame):
|
|
6304
6274
|
|
6305
6275
|
def align_index(
|
6306
6276
|
self,
|
6307
|
-
rows: list | dict | int
|
6277
|
+
rows: list[int] | dict[int, str] | int,
|
6308
6278
|
align: str | None = "global",
|
6309
6279
|
redraw: bool = True,
|
6310
6280
|
) -> Sheet:
|
@@ -6470,11 +6440,11 @@ class Sheet(tk.Frame):
|
|
6470
6440
|
c: int | Literal["all"] = 0,
|
6471
6441
|
) -> None:
|
6472
6442
|
if isinstance(r, str) and r.lower() == "all" and isinstance(c, int):
|
6473
|
-
for r_,
|
6443
|
+
for r_, _ in self.MT.cell_options:
|
6474
6444
|
if "checkbox" in self.MT.cell_options[(r_, c)]:
|
6475
6445
|
self.del_cell_options_checkbox(r_, c)
|
6476
6446
|
elif isinstance(c, str) and c.lower() == "all" and isinstance(r, int):
|
6477
|
-
for
|
6447
|
+
for _, c_ in self.MT.cell_options:
|
6478
6448
|
if "checkbox" in self.MT.cell_options[(r, c_)]:
|
6479
6449
|
self.del_cell_options_checkbox(r, c_)
|
6480
6450
|
elif isinstance(r, str) and r.lower() == "all" and isinstance(c, str) and c.lower() == "all":
|
@@ -6725,11 +6695,11 @@ class Sheet(tk.Frame):
|
|
6725
6695
|
c: int | Literal["all"] = 0,
|
6726
6696
|
) -> None:
|
6727
6697
|
if isinstance(r, str) and r.lower() == "all" and isinstance(c, int):
|
6728
|
-
for r_,
|
6698
|
+
for r_, _ in self.MT.cell_options:
|
6729
6699
|
if "dropdown" in self.MT.cell_options[(r_, c)]:
|
6730
6700
|
self.del_cell_options_dropdown(r_, c)
|
6731
6701
|
elif isinstance(c, str) and c.lower() == "all" and isinstance(r, int):
|
6732
|
-
for
|
6702
|
+
for _, c_ in self.MT.cell_options:
|
6733
6703
|
if "dropdown" in self.MT.cell_options[(r, c_)]:
|
6734
6704
|
self.del_cell_options_dropdown(r, c_)
|
6735
6705
|
elif isinstance(r, str) and r.lower() == "all" and isinstance(c, str) and c.lower() == "all":
|
@@ -6823,9 +6793,11 @@ class Sheet(tk.Frame):
|
|
6823
6793
|
r: int = 0,
|
6824
6794
|
c: int = 0,
|
6825
6795
|
set_existing_dropdown: bool = False,
|
6826
|
-
values: list[object] =
|
6796
|
+
values: list[object] | None = None,
|
6827
6797
|
set_value: object = None,
|
6828
6798
|
) -> Sheet:
|
6799
|
+
if values is None:
|
6800
|
+
values = []
|
6829
6801
|
if set_existing_dropdown:
|
6830
6802
|
if self.MT.dropdown.open:
|
6831
6803
|
r_, c_ = self.MT.dropdown.get_coords()
|
@@ -6848,9 +6820,11 @@ class Sheet(tk.Frame):
|
|
6848
6820
|
self,
|
6849
6821
|
c: int = 0,
|
6850
6822
|
set_existing_dropdown: bool = False,
|
6851
|
-
values: list[object] =
|
6823
|
+
values: list[object] | None = None,
|
6852
6824
|
set_value: object = None,
|
6853
6825
|
) -> Sheet:
|
6826
|
+
if values is None:
|
6827
|
+
values = []
|
6854
6828
|
if set_existing_dropdown:
|
6855
6829
|
if self.CH.dropdown.open:
|
6856
6830
|
c_ = self.CH.dropdown.get_coords()
|
@@ -6872,9 +6846,11 @@ class Sheet(tk.Frame):
|
|
6872
6846
|
self,
|
6873
6847
|
r: int = 0,
|
6874
6848
|
set_existing_dropdown: bool = False,
|
6875
|
-
values: list[object] =
|
6849
|
+
values: list[object] | None = None,
|
6876
6850
|
set_value: object = None,
|
6877
6851
|
) -> Sheet:
|
6852
|
+
if values is None:
|
6853
|
+
values = []
|
6878
6854
|
if set_existing_dropdown:
|
6879
6855
|
if self.RI.current_dropdown_window is not None:
|
6880
6856
|
r_ = self.RI.current_dropdown_window.r
|
@@ -6963,11 +6939,13 @@ class Sheet(tk.Frame):
|
|
6963
6939
|
self,
|
6964
6940
|
r: int | Literal["all"],
|
6965
6941
|
c: int | Literal["all"],
|
6966
|
-
formatter_options: dict =
|
6942
|
+
formatter_options: dict | None = None,
|
6967
6943
|
formatter_class: object = None,
|
6968
6944
|
redraw: bool = True,
|
6969
6945
|
**kwargs,
|
6970
6946
|
) -> Sheet:
|
6947
|
+
if formatter_options is None:
|
6948
|
+
formatter_options = {}
|
6971
6949
|
kwargs = fix_format_kwargs({"formatter": formatter_class, **formatter_options, **kwargs})
|
6972
6950
|
if isinstance(r, str) and r.lower() == "all" and isinstance(c, int):
|
6973
6951
|
for r_ in range(self.MT.total_data_rows()):
|
@@ -6996,11 +6974,11 @@ class Sheet(tk.Frame):
|
|
6996
6974
|
clear_values: bool = False,
|
6997
6975
|
) -> Sheet:
|
6998
6976
|
if isinstance(r, str) and r.lower() == "all" and isinstance(c, int):
|
6999
|
-
for r_,
|
6977
|
+
for r_, _ in self.MT.cell_options:
|
7000
6978
|
if "format" in self.MT.cell_options[(r_, c)]:
|
7001
6979
|
self.MT.delete_cell_format(r_, c, clear_values=clear_values)
|
7002
6980
|
elif isinstance(c, str) and c.lower() == "all" and isinstance(r, int):
|
7003
|
-
for
|
6981
|
+
for _, c_ in self.MT.cell_options:
|
7004
6982
|
if "format" in self.MT.cell_options[(r, c_)]:
|
7005
6983
|
self.MT.delete_cell_format(r, c_, clear_values=clear_values)
|
7006
6984
|
elif isinstance(r, str) and r.lower() == "all" and isinstance(c, str) and c.lower() == "all":
|
@@ -7014,11 +6992,13 @@ class Sheet(tk.Frame):
|
|
7014
6992
|
def format_row(
|
7015
6993
|
self,
|
7016
6994
|
r: AnyIter[int] | int | Literal["all"],
|
7017
|
-
formatter_options: dict =
|
6995
|
+
formatter_options: dict | None = None,
|
7018
6996
|
formatter_class: object = None,
|
7019
6997
|
redraw: bool = True,
|
7020
6998
|
**kwargs,
|
7021
6999
|
) -> Sheet:
|
7000
|
+
if formatter_options is None:
|
7001
|
+
formatter_options = {}
|
7022
7002
|
kwargs = fix_format_kwargs({"formatter": formatter_class, **formatter_options, **kwargs})
|
7023
7003
|
if isinstance(r, str) and r.lower() == "all":
|
7024
7004
|
for r_ in range(len(self.MT.data)):
|
@@ -7056,11 +7036,13 @@ class Sheet(tk.Frame):
|
|
7056
7036
|
def format_column(
|
7057
7037
|
self,
|
7058
7038
|
c: AnyIter[int] | int | Literal["all"],
|
7059
|
-
formatter_options: dict =
|
7039
|
+
formatter_options: dict | None = None,
|
7060
7040
|
formatter_class: object = None,
|
7061
7041
|
redraw: bool = True,
|
7062
7042
|
**kwargs,
|
7063
7043
|
) -> Sheet:
|
7044
|
+
if formatter_options is None:
|
7045
|
+
formatter_options = {}
|
7064
7046
|
kwargs = fix_format_kwargs({"formatter": formatter_class, **formatter_options, **kwargs})
|
7065
7047
|
if isinstance(c, str) and c.lower() == "all":
|
7066
7048
|
for c_ in range(self.MT.total_data_cols()):
|
@@ -7112,7 +7094,7 @@ class Dropdown(Sheet):
|
|
7112
7094
|
height: int | None = None,
|
7113
7095
|
font: None | tuple[str, int, str] = None,
|
7114
7096
|
outline_thickness: int = 2,
|
7115
|
-
values: list[object] =
|
7097
|
+
values: list[object] | None = None,
|
7116
7098
|
close_dropdown_window: Callable | None = None,
|
7117
7099
|
search_function: Callable = dropdown_search_function,
|
7118
7100
|
modified_function: None | Callable = None,
|
@@ -7170,7 +7152,7 @@ class Dropdown(Sheet):
|
|
7170
7152
|
ops=ops,
|
7171
7153
|
outline_color=outline_color,
|
7172
7154
|
align=align,
|
7173
|
-
values=values,
|
7155
|
+
values=[] if values is None else values,
|
7174
7156
|
search_function=search_function,
|
7175
7157
|
modified_function=modified_function,
|
7176
7158
|
)
|
@@ -7258,10 +7240,7 @@ class Dropdown(Sheet):
|
|
7258
7240
|
row = None
|
7259
7241
|
elif event.keysym == "Return":
|
7260
7242
|
row = self.get_selected_rows()
|
7261
|
-
if not row
|
7262
|
-
row = None
|
7263
|
-
else:
|
7264
|
-
row = next(iter(row))
|
7243
|
+
row = None if not row else next(iter(row))
|
7265
7244
|
else:
|
7266
7245
|
row = self.identify_row(event, exclude_index=True, allow_end=False)
|
7267
7246
|
if self.single_index:
|
@@ -7287,10 +7266,12 @@ class Dropdown(Sheet):
|
|
7287
7266
|
|
7288
7267
|
def values(
|
7289
7268
|
self,
|
7290
|
-
values: list =
|
7269
|
+
values: list[object] | None = None,
|
7291
7270
|
redraw: bool = True,
|
7292
7271
|
width: int | None = None,
|
7293
7272
|
) -> None:
|
7273
|
+
if values is None:
|
7274
|
+
values = []
|
7294
7275
|
self.set_sheet_data(
|
7295
7276
|
[[v] for v in values],
|
7296
7277
|
reset_col_positions=False,
|