tksheet 7.2.8__tar.gz → 7.2.10__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.2.8/tksheet.egg-info → tksheet-7.2.10}/PKG-INFO +1 -1
- {tksheet-7.2.8 → tksheet-7.2.10}/pyproject.toml +1 -1
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/__init__.py +1 -1
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/column_headers.py +20 -19
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/functions.py +1 -1
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/main_table.py +81 -70
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/row_index.py +40 -32
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/sheet.py +122 -58
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/top_left_rectangle.py +9 -10
- {tksheet-7.2.8 → tksheet-7.2.10/tksheet.egg-info}/PKG-INFO +1 -1
- {tksheet-7.2.8 → tksheet-7.2.10}/LICENSE.txt +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/README.md +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/setup.cfg +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/colors.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/formatters.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/other_classes.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/sheet_options.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/text_editor.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/themes.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/types.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/vars.py +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.2.8 → tksheet-7.2.10}/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 widget"
|
8
8
|
readme = "README.md"
|
9
|
-
version = "7.2.
|
9
|
+
version = "7.2.10"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -946,7 +946,7 @@ class ColumnHeaders(tk.Canvas):
|
|
946
946
|
run_binding_func: bool = True,
|
947
947
|
ext: bool = False,
|
948
948
|
) -> int:
|
949
|
-
boxes_to_hide = tuple(
|
949
|
+
boxes_to_hide = tuple(self.MT.selection_boxes)
|
950
950
|
fill_iid = self.MT.create_selection_box(0, c, len(self.MT.row_positions) - 1, c + 1, "columns", ext=ext)
|
951
951
|
for iid in boxes_to_hide:
|
952
952
|
self.MT.hide_selection_box(iid)
|
@@ -989,7 +989,7 @@ class ColumnHeaders(tk.Canvas):
|
|
989
989
|
y1,
|
990
990
|
x2,
|
991
991
|
y2,
|
992
|
-
radius=
|
992
|
+
radius=5 if self.PAR.ops.rounded_boxes else 0,
|
993
993
|
)
|
994
994
|
if isinstance(iid, int):
|
995
995
|
self.coords(iid, coords)
|
@@ -1314,24 +1314,23 @@ class ColumnHeaders(tk.Canvas):
|
|
1314
1314
|
if open_:
|
1315
1315
|
# up arrow
|
1316
1316
|
points = (
|
1317
|
-
x2 -
|
1317
|
+
x2 - 4 - small_mod - small_mod - small_mod - small_mod,
|
1318
1318
|
y1 + mid_y + small_mod,
|
1319
|
-
x2 -
|
1319
|
+
x2 - 4 - small_mod - small_mod,
|
1320
1320
|
y1 + mid_y - small_mod,
|
1321
|
-
x2 -
|
1321
|
+
x2 - 4,
|
1322
1322
|
y1 + mid_y + small_mod,
|
1323
1323
|
)
|
1324
1324
|
else:
|
1325
1325
|
# down arrow
|
1326
1326
|
points = (
|
1327
|
-
x2 -
|
1327
|
+
x2 - 4 - small_mod - small_mod - small_mod - small_mod,
|
1328
1328
|
y1 + mid_y - small_mod,
|
1329
|
-
x2 -
|
1329
|
+
x2 - 4 - small_mod - small_mod,
|
1330
1330
|
y1 + mid_y + small_mod,
|
1331
|
-
x2 -
|
1331
|
+
x2 - 4,
|
1332
1332
|
y1 + mid_y - small_mod,
|
1333
1333
|
)
|
1334
|
-
|
1335
1334
|
if self.hidd_dropdown:
|
1336
1335
|
t, sh = self.hidd_dropdown.popitem()
|
1337
1336
|
self.coords(t, points)
|
@@ -1341,10 +1340,13 @@ class ColumnHeaders(tk.Canvas):
|
|
1341
1340
|
self.itemconfig(t, fill=fill, tag=tag, state="normal")
|
1342
1341
|
self.lift(t)
|
1343
1342
|
else:
|
1344
|
-
t = self.
|
1343
|
+
t = self.create_line(
|
1345
1344
|
points,
|
1346
1345
|
fill=fill,
|
1347
1346
|
tag=tag,
|
1347
|
+
width=2,
|
1348
|
+
capstyle=tk.ROUND,
|
1349
|
+
joinstyle=tk.BEVEL,
|
1348
1350
|
)
|
1349
1351
|
self.disp_dropdown[t] = True
|
1350
1352
|
|
@@ -1758,8 +1760,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1758
1760
|
if self.text_editor.open and c == self.text_editor.column:
|
1759
1761
|
self.text_editor.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
|
1760
1762
|
return
|
1761
|
-
|
1762
|
-
self.hide_text_editor()
|
1763
|
+
self.hide_text_editor()
|
1763
1764
|
if not self.MT.see(r=0, c=c, keep_yscroll=True, check_cell_visibility=True):
|
1764
1765
|
self.MT.refresh()
|
1765
1766
|
x = self.MT.col_positions[c] + 1
|
@@ -1905,14 +1906,12 @@ class ColumnHeaders(tk.Canvas):
|
|
1905
1906
|
)
|
1906
1907
|
# self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
|
1907
1908
|
|
1908
|
-
def hide_text_editor(self
|
1909
|
+
def hide_text_editor(self) -> None:
|
1909
1910
|
if self.text_editor.open:
|
1910
1911
|
for binding in text_editor_to_unbind:
|
1911
1912
|
self.text_editor.tktext.unbind(binding)
|
1912
1913
|
self.itemconfig(self.text_editor.canvas_id, state="hidden")
|
1913
1914
|
self.text_editor.open = False
|
1914
|
-
if reason == "Escape":
|
1915
|
-
self.focus_set()
|
1916
1915
|
|
1917
1916
|
# c is displayed col
|
1918
1917
|
def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
|
@@ -1931,6 +1930,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1931
1930
|
return "break"
|
1932
1931
|
if event.keysym == "Escape":
|
1933
1932
|
self.hide_text_editor_and_dropdown()
|
1933
|
+
self.focus_set()
|
1934
1934
|
return
|
1935
1935
|
# setting cell data with text editor value
|
1936
1936
|
text_editor_value = self.text_editor.get()
|
@@ -2009,7 +2009,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2009
2009
|
dd_window.search_and_see(event)
|
2010
2010
|
|
2011
2011
|
def open_dropdown_window(self, c: int, event: object = None) -> None:
|
2012
|
-
self.hide_text_editor(
|
2012
|
+
self.hide_text_editor()
|
2013
2013
|
kwargs = self.get_cell_kwargs(self.MT.datacn(c), key="dropdown")
|
2014
2014
|
if kwargs["state"] == "normal":
|
2015
2015
|
if not self.open_text_editor(event=event, c=c, dropdown=True):
|
@@ -2073,8 +2073,9 @@ class ColumnHeaders(tk.Canvas):
|
|
2073
2073
|
return
|
2074
2074
|
redraw = False
|
2075
2075
|
else:
|
2076
|
-
self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(c))
|
2077
2076
|
self.update_idletasks()
|
2077
|
+
self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(c))
|
2078
|
+
self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
|
2078
2079
|
self.dropdown.window.focus_set()
|
2079
2080
|
redraw = True
|
2080
2081
|
self.dropdown.open = True
|
@@ -2114,12 +2115,12 @@ class ColumnHeaders(tk.Canvas):
|
|
2114
2115
|
edited = self.set_cell_data_undo(c, datacn=datacn, value=selection, redraw=not redraw)
|
2115
2116
|
if edited:
|
2116
2117
|
try_binding(self.extra_end_edit_cell_func, event_data)
|
2117
|
-
self.focus_set()
|
2118
2118
|
self.MT.recreate_all_selection_boxes()
|
2119
|
+
self.focus_set()
|
2119
2120
|
self.hide_text_editor_and_dropdown(redraw=redraw)
|
2120
2121
|
|
2121
2122
|
def hide_text_editor_and_dropdown(self, redraw: bool = True) -> None:
|
2122
|
-
self.hide_text_editor(
|
2123
|
+
self.hide_text_editor()
|
2123
2124
|
self.hide_dropdown_window()
|
2124
2125
|
if redraw:
|
2125
2126
|
self.MT.refresh()
|
@@ -25,6 +25,7 @@ from itertools import (
|
|
25
25
|
accumulate,
|
26
26
|
chain,
|
27
27
|
cycle,
|
28
|
+
filterfalse,
|
28
29
|
islice,
|
29
30
|
repeat,
|
30
31
|
)
|
@@ -696,8 +697,9 @@ class MainTable(tk.Canvas):
|
|
696
697
|
selected=self.selected,
|
697
698
|
)
|
698
699
|
if self.selected:
|
699
|
-
selected_r = self.selected.
|
700
|
-
selected_c = self.selected.
|
700
|
+
selected_r = self.selected.box.from_r
|
701
|
+
selected_c = self.selected.box.from_c
|
702
|
+
curr_coords = (self.selected.row, self.selected.column)
|
701
703
|
elif not self.selected and not self.PAR.ops.paste_can_expand_x and not self.PAR.ops.paste_can_expand_y:
|
702
704
|
return
|
703
705
|
else:
|
@@ -710,6 +712,7 @@ class MainTable(tk.Canvas):
|
|
710
712
|
selected_c, selected_r = len(self.col_positions) - 1, 0
|
711
713
|
elif len(self.row_positions) > 1 and len(self.col_positions) > 1:
|
712
714
|
selected_c, selected_r = 0, len(self.row_positions) - 1
|
715
|
+
curr_coords = (selected_r, selected_c)
|
713
716
|
try:
|
714
717
|
data = get_data_from_clipboard(
|
715
718
|
widget=self,
|
@@ -915,13 +918,17 @@ class MainTable(tk.Canvas):
|
|
915
918
|
else:
|
916
919
|
selboxc = selected_c_adjusted_new_data_numcols
|
917
920
|
self.deselect("all", redraw=False)
|
918
|
-
self.
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
921
|
+
self.set_currently_selected(
|
922
|
+
*curr_coords,
|
923
|
+
item=self.create_selection_box(
|
924
|
+
selected_r,
|
925
|
+
selected_c,
|
926
|
+
selboxr,
|
927
|
+
selboxc,
|
928
|
+
type_="cells",
|
929
|
+
set_current=False,
|
930
|
+
run_binding=True,
|
931
|
+
),
|
925
932
|
)
|
926
933
|
event_data["selection_boxes"] = self.get_boxes()
|
927
934
|
event_data["selected"] = self.selected
|
@@ -1789,9 +1796,7 @@ class MainTable(tk.Canvas):
|
|
1789
1796
|
def cell_visible(self, r: int = 0, c: int = 0) -> bool:
|
1790
1797
|
cx1, cy1, cx2, cy2 = self.get_canvas_visible_area()
|
1791
1798
|
x1, y1, x2, y2 = self.get_cell_coords(r, c)
|
1792
|
-
|
1793
|
-
return True
|
1794
|
-
return False
|
1799
|
+
return x1 <= cx2 or y1 <= cy2 or x2 >= cx1 or y2 >= cy1
|
1795
1800
|
|
1796
1801
|
def select_all(self, redraw: bool = True, run_binding_func: bool = True) -> None:
|
1797
1802
|
selected = self.selected
|
@@ -3773,11 +3778,10 @@ class MainTable(tk.Canvas):
|
|
3773
3778
|
colpos = self.PAR.ops.default_column_width
|
3774
3779
|
if isinstance(ncols, int):
|
3775
3780
|
self.set_col_positions(itr=repeat(colpos, ncols))
|
3781
|
+
elif self.all_columns_displayed:
|
3782
|
+
self.set_col_positions(itr=repeat(colpos, self.total_data_cols()))
|
3776
3783
|
else:
|
3777
|
-
|
3778
|
-
self.set_col_positions(itr=repeat(colpos, self.total_data_cols()))
|
3779
|
-
else:
|
3780
|
-
self.set_col_positions(itr=repeat(colpos, len(self.displayed_columns)))
|
3784
|
+
self.set_col_positions(itr=repeat(colpos, len(self.displayed_columns)))
|
3781
3785
|
|
3782
3786
|
def set_row_positions(self, itr: Iterator[float]) -> None:
|
3783
3787
|
self.row_positions = list(accumulate(chain([0], itr)))
|
@@ -3786,11 +3790,10 @@ class MainTable(tk.Canvas):
|
|
3786
3790
|
rowpos = self.get_default_row_height()
|
3787
3791
|
if isinstance(nrows, int):
|
3788
3792
|
self.set_row_positions(itr=repeat(rowpos, nrows))
|
3793
|
+
elif self.all_rows_displayed:
|
3794
|
+
self.set_row_positions(itr=repeat(rowpos, self.total_data_rows()))
|
3789
3795
|
else:
|
3790
|
-
|
3791
|
-
self.set_row_positions(itr=repeat(rowpos, self.total_data_rows()))
|
3792
|
-
else:
|
3793
|
-
self.set_row_positions(itr=repeat(rowpos, len(self.displayed_rows)))
|
3796
|
+
self.set_row_positions(itr=repeat(rowpos, len(self.displayed_rows)))
|
3794
3797
|
|
3795
3798
|
def del_col_position(self, idx: int, deselect_all: bool = False):
|
3796
3799
|
if deselect_all:
|
@@ -4453,7 +4456,7 @@ class MainTable(tk.Canvas):
|
|
4453
4456
|
if isinstance(displayed_rows, list):
|
4454
4457
|
self.displayed_rows = displayed_rows
|
4455
4458
|
elif not self.all_rows_displayed:
|
4456
|
-
# push displayed indexes by one for every inserted
|
4459
|
+
# push displayed indexes by one for every inserted row
|
4457
4460
|
self.displayed_rows.sort()
|
4458
4461
|
# highest index is first in rows
|
4459
4462
|
up_to = len(self.displayed_rows)
|
@@ -4718,9 +4721,10 @@ class MainTable(tk.Canvas):
|
|
4718
4721
|
named_spans=self.get_spans_to_del_from_cols(cols=cols_set),
|
4719
4722
|
)
|
4720
4723
|
if not self.all_columns_displayed:
|
4721
|
-
self.displayed_columns = [
|
4722
|
-
|
4723
|
-
|
4724
|
+
self.displayed_columns = [
|
4725
|
+
c if not (num := bisect_left(cols, c)) else c - num
|
4726
|
+
for c in filterfalse(cols_set.__contains__, self.displayed_columns)
|
4727
|
+
]
|
4724
4728
|
return event_data
|
4725
4729
|
|
4726
4730
|
def delete_columns_displayed(self, cols: list, event_data: dict) -> EventDataDict:
|
@@ -4773,9 +4777,10 @@ class MainTable(tk.Canvas):
|
|
4773
4777
|
named_spans=self.get_spans_to_del_from_rows(rows=rows_set),
|
4774
4778
|
)
|
4775
4779
|
if not self.all_rows_displayed:
|
4776
|
-
self.displayed_rows = [
|
4777
|
-
|
4778
|
-
|
4780
|
+
self.displayed_rows = [
|
4781
|
+
r if not (num := bisect_left(rows, r)) else r - num
|
4782
|
+
for r in filterfalse(rows_set.__contains__, self.displayed_rows)
|
4783
|
+
]
|
4779
4784
|
return event_data
|
4780
4785
|
|
4781
4786
|
def delete_rows_displayed(self, rows: list, event_data: dict) -> EventDataDict:
|
@@ -4847,20 +4852,23 @@ class MainTable(tk.Canvas):
|
|
4847
4852
|
) -> list[int] | None:
|
4848
4853
|
if rows is None and all_rows_displayed is None:
|
4849
4854
|
return list(range(self.total_data_rows())) if self.all_rows_displayed else self.displayed_rows
|
4850
|
-
total_data_rows = None
|
4851
|
-
if (rows is not None and rows != self.displayed_rows) or (all_rows_displayed and not self.all_rows_displayed):
|
4852
|
-
self.purge_undo_and_redo_stack()
|
4853
4855
|
if rows is not None and rows != self.displayed_rows:
|
4856
|
+
self.purge_undo_and_redo_stack()
|
4854
4857
|
self.displayed_rows = sorted(rows)
|
4855
|
-
|
4856
|
-
|
4857
|
-
|
4858
|
-
|
4859
|
-
|
4860
|
-
|
4861
|
-
|
4858
|
+
# setting all_rows_displayed
|
4859
|
+
if all_rows_displayed is not None:
|
4860
|
+
# setting it to True and it's currently False
|
4861
|
+
if all_rows_displayed and not self.all_rows_displayed:
|
4862
|
+
self.purge_undo_and_redo_stack()
|
4863
|
+
self.all_rows_displayed = True
|
4864
|
+
# setting it to False and it's currently True
|
4865
|
+
elif not all_rows_displayed and self.all_rows_displayed:
|
4866
|
+
# if rows is None then displayed_rows needs to be reset
|
4867
|
+
if rows is None:
|
4868
|
+
self.displayed_rows = list(range(self.total_data_rows()))
|
4869
|
+
self.all_rows_displayed = False
|
4862
4870
|
if reset_row_positions:
|
4863
|
-
self.reset_row_positions(
|
4871
|
+
self.reset_row_positions()
|
4864
4872
|
if deselect_all:
|
4865
4873
|
self.deselect("all", redraw=False)
|
4866
4874
|
|
@@ -4873,22 +4881,23 @@ class MainTable(tk.Canvas):
|
|
4873
4881
|
) -> list[int] | None:
|
4874
4882
|
if columns is None and all_columns_displayed is None:
|
4875
4883
|
return list(range(self.total_data_cols())) if self.all_columns_displayed else self.displayed_columns
|
4876
|
-
total_data_cols = None
|
4877
|
-
if (columns is not None and columns != self.displayed_columns) or (
|
4878
|
-
all_columns_displayed and not self.all_columns_displayed
|
4879
|
-
):
|
4880
|
-
self.purge_undo_and_redo_stack()
|
4881
4884
|
if columns is not None and columns != self.displayed_columns:
|
4885
|
+
self.purge_undo_and_redo_stack()
|
4882
4886
|
self.displayed_columns = sorted(columns)
|
4883
|
-
|
4884
|
-
|
4885
|
-
|
4886
|
-
|
4887
|
-
|
4888
|
-
|
4889
|
-
|
4887
|
+
# setting all_columns_displayed
|
4888
|
+
if all_columns_displayed is not None:
|
4889
|
+
# setting it to True and it's currently False
|
4890
|
+
if all_columns_displayed and not self.all_columns_displayed:
|
4891
|
+
self.purge_undo_and_redo_stack()
|
4892
|
+
self.all_columns_displayed = True
|
4893
|
+
# setting it to False and it's currently True
|
4894
|
+
elif not all_columns_displayed and self.all_columns_displayed:
|
4895
|
+
# if columns is None then displayed_columns needs to be reset
|
4896
|
+
if columns is None:
|
4897
|
+
self.displayed_columns = list(range(self.total_data_cols()))
|
4898
|
+
self.all_columns_displayed = False
|
4890
4899
|
if reset_col_positions:
|
4891
|
-
self.reset_col_positions(
|
4900
|
+
self.reset_col_positions()
|
4892
4901
|
if deselect_all:
|
4893
4902
|
self.deselect("all", redraw=False)
|
4894
4903
|
|
@@ -5245,21 +5254,21 @@ class MainTable(tk.Canvas):
|
|
5245
5254
|
if open_:
|
5246
5255
|
# up arrow
|
5247
5256
|
points = (
|
5248
|
-
x2 -
|
5257
|
+
x2 - 4 - small_mod - small_mod - small_mod - small_mod,
|
5249
5258
|
y1 + mid_y + small_mod,
|
5250
|
-
x2 -
|
5259
|
+
x2 - 4 - small_mod - small_mod,
|
5251
5260
|
y1 + mid_y - small_mod,
|
5252
|
-
x2 -
|
5261
|
+
x2 - 4,
|
5253
5262
|
y1 + mid_y + small_mod,
|
5254
5263
|
)
|
5255
5264
|
else:
|
5256
5265
|
# down arrow
|
5257
5266
|
points = (
|
5258
|
-
x2 -
|
5267
|
+
x2 - 4 - small_mod - small_mod - small_mod - small_mod,
|
5259
5268
|
y1 + mid_y - small_mod,
|
5260
|
-
x2 -
|
5269
|
+
x2 - 4 - small_mod - small_mod,
|
5261
5270
|
y1 + mid_y + small_mod,
|
5262
|
-
x2 -
|
5271
|
+
x2 - 4,
|
5263
5272
|
y1 + mid_y - small_mod,
|
5264
5273
|
)
|
5265
5274
|
if self.hidd_dropdown:
|
@@ -5271,10 +5280,13 @@ class MainTable(tk.Canvas):
|
|
5271
5280
|
self.itemconfig(t, fill=fill, tag=tag, state="normal")
|
5272
5281
|
self.lift(t)
|
5273
5282
|
else:
|
5274
|
-
t = self.
|
5283
|
+
t = self.create_line(
|
5275
5284
|
points,
|
5276
5285
|
fill=fill,
|
5277
5286
|
tag=tag,
|
5287
|
+
width=2,
|
5288
|
+
capstyle=tk.ROUND,
|
5289
|
+
joinstyle=tk.BEVEL,
|
5278
5290
|
)
|
5279
5291
|
self.disp_dropdown[t] = True
|
5280
5292
|
|
@@ -5443,7 +5455,7 @@ class MainTable(tk.Canvas):
|
|
5443
5455
|
if self.PAR.ops.auto_resize_row_index and redraw_row_index and self.show_index:
|
5444
5456
|
changed_w = self.RI.auto_set_index_width(
|
5445
5457
|
end_row=grid_end_row,
|
5446
|
-
only_rows=
|
5458
|
+
only_rows=map(self.datarn, range(text_start_row, text_end_row)),
|
5447
5459
|
)
|
5448
5460
|
if resized_cols or resized_rows or changed_w:
|
5449
5461
|
self.recreate_all_selection_boxes()
|
@@ -5957,7 +5969,7 @@ class MainTable(tk.Canvas):
|
|
5957
5969
|
if not self.PAR.ops.rounded_boxes or not x2 - x1 or not y2 - y1:
|
5958
5970
|
radius = 0
|
5959
5971
|
else:
|
5960
|
-
radius =
|
5972
|
+
radius = 5
|
5961
5973
|
coords = rounded_box_coords(
|
5962
5974
|
x1,
|
5963
5975
|
y1,
|
@@ -6182,7 +6194,7 @@ class MainTable(tk.Canvas):
|
|
6182
6194
|
x1, y1, x2, y2 = self.box_coords_x_canvas_coords(r1, c1, r2, c2, type_)
|
6183
6195
|
self.display_box(x1, y1, x2, y2, fill=mt_bg, outline="", state=state, tags=type_, width=1, iid=fill_iid)
|
6184
6196
|
self.RI.display_box(
|
6185
|
-
|
6197
|
+
0,
|
6186
6198
|
y1,
|
6187
6199
|
self.RI.current_width - 1,
|
6188
6200
|
y2,
|
@@ -6558,8 +6570,7 @@ class MainTable(tk.Canvas):
|
|
6558
6570
|
if self.text_editor.open and (r, c) == self.text_editor.coords:
|
6559
6571
|
self.text_editor.window.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
|
6560
6572
|
return
|
6561
|
-
|
6562
|
-
self.hide_text_editor()
|
6573
|
+
self.hide_text_editor()
|
6563
6574
|
if not self.see(r=r, c=c, check_cell_visibility=True):
|
6564
6575
|
self.refresh()
|
6565
6576
|
x = self.col_positions[c]
|
@@ -6693,14 +6704,12 @@ class MainTable(tk.Canvas):
|
|
6693
6704
|
)
|
6694
6705
|
# self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
|
6695
6706
|
|
6696
|
-
def hide_text_editor(self
|
6707
|
+
def hide_text_editor(self) -> None:
|
6697
6708
|
if self.text_editor.open:
|
6698
6709
|
for binding in text_editor_to_unbind:
|
6699
6710
|
self.text_editor.tktext.unbind(binding)
|
6700
6711
|
self.itemconfig(self.text_editor.canvas_id, state="hidden")
|
6701
6712
|
self.text_editor.open = False
|
6702
|
-
if reason == "Escape":
|
6703
|
-
self.focus_set()
|
6704
6713
|
|
6705
6714
|
def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
|
6706
6715
|
# checking if text editor should be closed or not
|
@@ -6718,6 +6727,7 @@ class MainTable(tk.Canvas):
|
|
6718
6727
|
return "break"
|
6719
6728
|
if event.keysym == "Escape":
|
6720
6729
|
self.hide_text_editor_and_dropdown()
|
6730
|
+
self.focus_set()
|
6721
6731
|
return
|
6722
6732
|
# setting cell data with text editor value
|
6723
6733
|
text_editor_value = self.text_editor.get()
|
@@ -6930,7 +6940,7 @@ class MainTable(tk.Canvas):
|
|
6930
6940
|
c: int,
|
6931
6941
|
event: object = None,
|
6932
6942
|
) -> None:
|
6933
|
-
self.hide_text_editor(
|
6943
|
+
self.hide_text_editor()
|
6934
6944
|
datarn = self.datarn(r)
|
6935
6945
|
datacn = self.datacn(c)
|
6936
6946
|
kwargs = self.get_cell_kwargs(datarn, datacn, key="dropdown")
|
@@ -7005,7 +7015,8 @@ class MainTable(tk.Canvas):
|
|
7005
7015
|
else:
|
7006
7016
|
self.update_idletasks()
|
7007
7017
|
self.dropdown.window.bind("<FocusOut>", lambda _: self.close_dropdown_window(r, c))
|
7008
|
-
self.dropdown.window.
|
7018
|
+
self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
|
7019
|
+
self.dropdown.window.focus_set()
|
7009
7020
|
redraw = True
|
7010
7021
|
self.dropdown.open = True
|
7011
7022
|
if redraw:
|
@@ -7061,12 +7072,12 @@ class MainTable(tk.Canvas):
|
|
7061
7072
|
)
|
7062
7073
|
if edited:
|
7063
7074
|
try_binding(self.extra_end_edit_cell_func, event_data)
|
7064
|
-
self.focus_set()
|
7065
7075
|
self.recreate_all_selection_boxes()
|
7076
|
+
self.focus_set()
|
7066
7077
|
self.hide_text_editor_and_dropdown(redraw=redraw)
|
7067
7078
|
|
7068
7079
|
def hide_text_editor_and_dropdown(self, redraw: bool = True) -> None:
|
7069
|
-
self.hide_text_editor(
|
7080
|
+
self.hide_text_editor()
|
7070
7081
|
self.hide_dropdown_window()
|
7071
7082
|
if redraw:
|
7072
7083
|
self.refresh()
|
@@ -358,7 +358,16 @@ class RowIndex(tk.Canvas):
|
|
358
358
|
self.MT.current_cursor = "sb_v_double_arrow"
|
359
359
|
else:
|
360
360
|
self.rsz_h = None
|
361
|
-
if
|
361
|
+
if (
|
362
|
+
self.width_resizing_enabled
|
363
|
+
and not mouse_over_resize
|
364
|
+
and self.PAR.ops.auto_resize_row_index is not True
|
365
|
+
and not (
|
366
|
+
self.PAR.ops.auto_resize_row_index == "empty"
|
367
|
+
and not isinstance(self.MT._row_index, int)
|
368
|
+
and not self.MT._row_index
|
369
|
+
)
|
370
|
+
):
|
362
371
|
try:
|
363
372
|
x1, y1, x2, y2 = (
|
364
373
|
self.row_width_resize_bbox[0],
|
@@ -761,22 +770,18 @@ class RowIndex(tk.Canvas):
|
|
761
770
|
self.MT.set_yviews("moveto", 1)
|
762
771
|
|
763
772
|
def event_over_dropdown(self, r: int, datarn: int, event: object, canvasy: float) -> bool:
|
764
|
-
|
773
|
+
return (
|
765
774
|
canvasy < self.MT.row_positions[r] + self.MT.index_txt_height
|
766
775
|
and self.get_cell_kwargs(datarn, key="dropdown")
|
767
776
|
and event.x > self.current_width - self.MT.index_txt_height - 4
|
768
|
-
)
|
769
|
-
return True
|
770
|
-
return False
|
777
|
+
)
|
771
778
|
|
772
779
|
def event_over_checkbox(self, r: int, datarn: int, event: object, canvasy: float) -> bool:
|
773
|
-
|
780
|
+
return (
|
774
781
|
canvasy < self.MT.row_positions[r] + self.MT.index_txt_height
|
775
782
|
and self.get_cell_kwargs(datarn, key="checkbox")
|
776
783
|
and event.x < self.MT.index_txt_height + 4
|
777
|
-
)
|
778
|
-
return True
|
779
|
-
return False
|
784
|
+
)
|
780
785
|
|
781
786
|
def b1_release(self, event: object) -> None:
|
782
787
|
if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
|
@@ -957,7 +962,7 @@ class RowIndex(tk.Canvas):
|
|
957
962
|
run_binding_func: bool = True,
|
958
963
|
ext: bool = False,
|
959
964
|
) -> int:
|
960
|
-
boxes_to_hide = tuple(
|
965
|
+
boxes_to_hide = tuple(self.MT.selection_boxes)
|
961
966
|
fill_iid = self.MT.create_selection_box(r, 0, r + 1, len(self.MT.col_positions) - 1, "rows", ext=ext)
|
962
967
|
for iid in boxes_to_hide:
|
963
968
|
self.MT.hide_selection_box(iid)
|
@@ -1000,7 +1005,7 @@ class RowIndex(tk.Canvas):
|
|
1000
1005
|
y1,
|
1001
1006
|
x2,
|
1002
1007
|
y2,
|
1003
|
-
radius=
|
1008
|
+
radius=5 if self.PAR.ops.rounded_boxes else 0,
|
1004
1009
|
)
|
1005
1010
|
if isinstance(iid, int):
|
1006
1011
|
self.coords(iid, coords)
|
@@ -1353,11 +1358,9 @@ class RowIndex(tk.Canvas):
|
|
1353
1358
|
# the left hand downward point
|
1354
1359
|
x1 + 5 + indent,
|
1355
1360
|
y1 + mid_y + small_mod,
|
1356
|
-
|
1357
1361
|
# the middle upward point
|
1358
1362
|
x1 + 5 + indent + small_mod + small_mod,
|
1359
1363
|
y1 + mid_y - small_mod,
|
1360
|
-
|
1361
1364
|
# the right hand downward point
|
1362
1365
|
x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
|
1363
1366
|
y1 + mid_y + small_mod,
|
@@ -1368,11 +1371,9 @@ class RowIndex(tk.Canvas):
|
|
1368
1371
|
# the upper point
|
1369
1372
|
x1 + 5 + indent + small_mod + small_mod,
|
1370
1373
|
y1 + mid_y - small_mod - small_mod,
|
1371
|
-
|
1372
1374
|
# the middle point
|
1373
1375
|
x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
|
1374
1376
|
y1 + mid_y,
|
1375
|
-
|
1376
1377
|
# the bottom point
|
1377
1378
|
x1 + 5 + indent + small_mod + small_mod,
|
1378
1379
|
y1 + mid_y + small_mod + small_mod,
|
@@ -1418,21 +1419,21 @@ class RowIndex(tk.Canvas):
|
|
1418
1419
|
if open_:
|
1419
1420
|
# up arrow
|
1420
1421
|
points = (
|
1421
|
-
x2 -
|
1422
|
+
x2 - 4 - small_mod - small_mod - small_mod - small_mod,
|
1422
1423
|
y1 + mid_y + small_mod,
|
1423
|
-
x2 -
|
1424
|
+
x2 - 4 - small_mod - small_mod,
|
1424
1425
|
y1 + mid_y - small_mod,
|
1425
|
-
x2 -
|
1426
|
+
x2 - 4,
|
1426
1427
|
y1 + mid_y + small_mod,
|
1427
1428
|
)
|
1428
1429
|
else:
|
1429
1430
|
# down arrow
|
1430
1431
|
points = (
|
1431
|
-
x2 -
|
1432
|
+
x2 - 4 - small_mod - small_mod - small_mod - small_mod,
|
1432
1433
|
y1 + mid_y - small_mod,
|
1433
|
-
x2 -
|
1434
|
+
x2 - 4 - small_mod - small_mod,
|
1434
1435
|
y1 + mid_y + small_mod,
|
1435
|
-
x2 -
|
1436
|
+
x2 - 4,
|
1436
1437
|
y1 + mid_y - small_mod,
|
1437
1438
|
)
|
1438
1439
|
if self.hidd_dropdown:
|
@@ -1444,10 +1445,13 @@ class RowIndex(tk.Canvas):
|
|
1444
1445
|
self.itemconfig(t, fill=fill, tag=tag, state="normal")
|
1445
1446
|
self.lift(t)
|
1446
1447
|
else:
|
1447
|
-
t = self.
|
1448
|
+
t = self.create_line(
|
1448
1449
|
points,
|
1449
1450
|
fill=fill,
|
1450
1451
|
tag=tag,
|
1452
|
+
width=2,
|
1453
|
+
capstyle=tk.ROUND,
|
1454
|
+
joinstyle=tk.BEVEL,
|
1451
1455
|
)
|
1452
1456
|
self.disp_dropdown[t] = True
|
1453
1457
|
|
@@ -1892,8 +1896,7 @@ class RowIndex(tk.Canvas):
|
|
1892
1896
|
if self.text_editor.open and r == self.text_editor.row:
|
1893
1897
|
self.text_editor.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
|
1894
1898
|
return
|
1895
|
-
|
1896
|
-
self.hide_text_editor()
|
1899
|
+
self.hide_text_editor()
|
1897
1900
|
if not self.MT.see(r=r, c=0, keep_yscroll=True, check_cell_visibility=True):
|
1898
1901
|
self.MT.refresh()
|
1899
1902
|
x = 0
|
@@ -2026,14 +2029,12 @@ class RowIndex(tk.Canvas):
|
|
2026
2029
|
)
|
2027
2030
|
# self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
|
2028
2031
|
|
2029
|
-
def hide_text_editor(self
|
2032
|
+
def hide_text_editor(self) -> None:
|
2030
2033
|
if self.text_editor.open:
|
2031
2034
|
for binding in text_editor_to_unbind:
|
2032
2035
|
self.text_editor.tktext.unbind(binding)
|
2033
2036
|
self.itemconfig(self.text_editor.canvas_id, state="hidden")
|
2034
2037
|
self.text_editor.open = False
|
2035
|
-
if reason == "Escape":
|
2036
|
-
self.focus_set()
|
2037
2038
|
|
2038
2039
|
# r is displayed row
|
2039
2040
|
def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
|
@@ -2052,6 +2053,7 @@ class RowIndex(tk.Canvas):
|
|
2052
2053
|
return "break"
|
2053
2054
|
if event.keysym == "Escape":
|
2054
2055
|
self.hide_text_editor_and_dropdown()
|
2056
|
+
self.focus_set()
|
2055
2057
|
return
|
2056
2058
|
text_editor_value = self.text_editor.get()
|
2057
2059
|
r = self.text_editor.row
|
@@ -2133,7 +2135,7 @@ class RowIndex(tk.Canvas):
|
|
2133
2135
|
|
2134
2136
|
# r is displayed row
|
2135
2137
|
def open_dropdown_window(self, r: int, event: object = None) -> None:
|
2136
|
-
self.hide_text_editor(
|
2138
|
+
self.hide_text_editor()
|
2137
2139
|
kwargs = self.get_cell_kwargs(self.MT.datarn(r), key="dropdown")
|
2138
2140
|
if kwargs["state"] == "normal":
|
2139
2141
|
if not self.open_text_editor(event=event, r=r, dropdown=True):
|
@@ -2204,8 +2206,9 @@ class RowIndex(tk.Canvas):
|
|
2204
2206
|
return
|
2205
2207
|
redraw = False
|
2206
2208
|
else:
|
2207
|
-
self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(r))
|
2208
2209
|
self.update_idletasks()
|
2210
|
+
self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(r))
|
2211
|
+
self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
|
2209
2212
|
self.dropdown.window.focus_set()
|
2210
2213
|
redraw = True
|
2211
2214
|
self.dropdown.open = True
|
@@ -2246,12 +2249,12 @@ class RowIndex(tk.Canvas):
|
|
2246
2249
|
edited = self.set_cell_data_undo(r, datarn=datarn, value=selection, redraw=not redraw)
|
2247
2250
|
if edited:
|
2248
2251
|
try_binding(self.extra_end_edit_cell_func, event_data)
|
2249
|
-
self.focus_set()
|
2250
2252
|
self.MT.recreate_all_selection_boxes()
|
2253
|
+
self.focus_set()
|
2251
2254
|
self.hide_text_editor_and_dropdown(redraw=redraw)
|
2252
2255
|
|
2253
2256
|
def hide_text_editor_and_dropdown(self, redraw: bool = True) -> None:
|
2254
|
-
self.hide_text_editor(
|
2257
|
+
self.hide_text_editor()
|
2255
2258
|
self.hide_dropdown_window()
|
2256
2259
|
if redraw:
|
2257
2260
|
self.MT.refresh()
|
@@ -2521,7 +2524,7 @@ class RowIndex(tk.Canvas):
|
|
2521
2524
|
if not node.parent.children:
|
2522
2525
|
self.tree_open_ids.discard(node.parent)
|
2523
2526
|
|
2524
|
-
def
|
2527
|
+
def build_pid_causes_recursive_loop(self, iid: str, pid: str) -> bool:
|
2525
2528
|
return any(
|
2526
2529
|
i == pid
|
2527
2530
|
for i in chain(
|
@@ -2529,3 +2532,8 @@ class RowIndex(tk.Canvas):
|
|
2529
2532
|
islice(self.get_iid_ancestors(iid), 1, None),
|
2530
2533
|
)
|
2531
2534
|
)
|
2535
|
+
|
2536
|
+
def move_pid_causes_recursive_loop(self, to_move_iid: str, move_to_parent: str) -> bool:
|
2537
|
+
# if the parent the item is being moved under is one of the item's descendants
|
2538
|
+
# then it is a recursive loop
|
2539
|
+
return any(move_to_parent == diid for diid in self.get_iid_descendants(to_move_iid))
|
@@ -10,7 +10,14 @@ from collections.abc import (
|
|
10
10
|
Iterator,
|
11
11
|
Sequence,
|
12
12
|
)
|
13
|
-
from itertools import
|
13
|
+
from itertools import (
|
14
|
+
accumulate,
|
15
|
+
chain,
|
16
|
+
filterfalse,
|
17
|
+
islice,
|
18
|
+
product,
|
19
|
+
repeat,
|
20
|
+
)
|
14
21
|
from timeit import default_timer
|
15
22
|
from tkinter import ttk
|
16
23
|
from typing import Literal
|
@@ -3813,7 +3820,6 @@ class Sheet(tk.Frame):
|
|
3813
3820
|
columns: None | Literal["all"] | Iterator[int] = None,
|
3814
3821
|
all_columns_displayed: None | bool = None,
|
3815
3822
|
reset_col_positions: bool = True,
|
3816
|
-
refresh: bool = False,
|
3817
3823
|
redraw: bool = False,
|
3818
3824
|
deselect_all: bool = True,
|
3819
3825
|
**kwargs,
|
@@ -3828,8 +3834,9 @@ class Sheet(tk.Frame):
|
|
3828
3834
|
reset_col_positions=reset_col_positions,
|
3829
3835
|
deselect_all=deselect_all,
|
3830
3836
|
)
|
3831
|
-
if refresh
|
3832
|
-
|
3837
|
+
if "refresh" in kwargs:
|
3838
|
+
redraw = kwargs["refresh"]
|
3839
|
+
self.set_refresh_timer(redraw)
|
3833
3840
|
return res
|
3834
3841
|
|
3835
3842
|
def hide_columns(
|
@@ -3846,7 +3853,7 @@ class Sheet(tk.Frame):
|
|
3846
3853
|
if not columns:
|
3847
3854
|
return
|
3848
3855
|
if self.MT.all_columns_displayed:
|
3849
|
-
self.MT.displayed_columns =
|
3856
|
+
self.MT.displayed_columns = list(filterfalse(columns.__contains__, range(self.MT.total_data_cols())))
|
3850
3857
|
to_pop = {c: c for c in columns}
|
3851
3858
|
else:
|
3852
3859
|
to_pop = {}
|
@@ -3876,13 +3883,18 @@ class Sheet(tk.Frame):
|
|
3876
3883
|
self.MT.deselect(redraw=False)
|
3877
3884
|
return self.set_refresh_timer(redraw)
|
3878
3885
|
|
3879
|
-
# uses data indexes
|
3880
3886
|
def show_columns(
|
3881
3887
|
self,
|
3882
3888
|
columns: int | Iterator[int],
|
3883
3889
|
redraw: bool = True,
|
3884
3890
|
deselect_all: bool = True,
|
3885
3891
|
) -> Sheet:
|
3892
|
+
"""
|
3893
|
+
'columns' argument must be data indexes
|
3894
|
+
Function will return without action if Sheet.all_columns
|
3895
|
+
"""
|
3896
|
+
if self.MT.all_columns_displayed:
|
3897
|
+
return
|
3886
3898
|
if isinstance(columns, int):
|
3887
3899
|
columns = [columns]
|
3888
3900
|
cws = self.MT.get_column_widths()
|
@@ -3908,7 +3920,10 @@ class Sheet(tk.Frame):
|
|
3908
3920
|
|
3909
3921
|
@all_columns.setter
|
3910
3922
|
def all_columns(self, a: bool) -> Sheet:
|
3911
|
-
self.MT.
|
3923
|
+
self.MT.display_columns(
|
3924
|
+
columns=None,
|
3925
|
+
all_columns_displayed=a,
|
3926
|
+
)
|
3912
3927
|
return self
|
3913
3928
|
|
3914
3929
|
@property
|
@@ -3917,8 +3932,8 @@ class Sheet(tk.Frame):
|
|
3917
3932
|
|
3918
3933
|
@displayed_columns.setter
|
3919
3934
|
def displayed_columns(self, columns: list[int]) -> Sheet:
|
3920
|
-
self.display_columns(columns=columns, reset_col_positions=
|
3921
|
-
return self
|
3935
|
+
self.display_columns(columns=columns, reset_col_positions=True, redraw=False)
|
3936
|
+
return self.set_refresh_timer()
|
3922
3937
|
|
3923
3938
|
# Hiding Rows
|
3924
3939
|
|
@@ -3933,7 +3948,6 @@ class Sheet(tk.Frame):
|
|
3933
3948
|
rows: None | Literal["all"] | Iterator[int] = None,
|
3934
3949
|
all_rows_displayed: None | bool = None,
|
3935
3950
|
reset_row_positions: bool = True,
|
3936
|
-
refresh: bool = False,
|
3937
3951
|
redraw: bool = False,
|
3938
3952
|
deselect_all: bool = True,
|
3939
3953
|
**kwargs,
|
@@ -3946,8 +3960,9 @@ class Sheet(tk.Frame):
|
|
3946
3960
|
reset_row_positions=reset_row_positions,
|
3947
3961
|
deselect_all=deselect_all,
|
3948
3962
|
)
|
3949
|
-
if refresh
|
3950
|
-
|
3963
|
+
if "refresh" in kwargs:
|
3964
|
+
redraw = kwargs["refresh"]
|
3965
|
+
self.set_refresh_timer(redraw)
|
3951
3966
|
return res
|
3952
3967
|
|
3953
3968
|
def hide_rows(
|
@@ -3965,7 +3980,7 @@ class Sheet(tk.Frame):
|
|
3965
3980
|
if not rows:
|
3966
3981
|
return
|
3967
3982
|
if self.MT.all_rows_displayed:
|
3968
|
-
self.MT.displayed_rows =
|
3983
|
+
self.MT.displayed_rows = list(filterfalse(rows.__contains__, range(self.MT.total_data_rows())))
|
3969
3984
|
to_pop = {r: r for r in rows}
|
3970
3985
|
else:
|
3971
3986
|
to_pop = {}
|
@@ -3996,13 +4011,18 @@ class Sheet(tk.Frame):
|
|
3996
4011
|
self.MT.deselect(redraw=False)
|
3997
4012
|
return self.set_refresh_timer(redraw)
|
3998
4013
|
|
3999
|
-
# uses data indexes
|
4000
4014
|
def show_rows(
|
4001
4015
|
self,
|
4002
4016
|
rows: int | Iterator[int],
|
4003
4017
|
redraw: bool = True,
|
4004
4018
|
deselect_all: bool = True,
|
4005
4019
|
) -> Sheet:
|
4020
|
+
"""
|
4021
|
+
'rows' argument must be data indexes
|
4022
|
+
Function will return without action if Sheet.all_rows
|
4023
|
+
"""
|
4024
|
+
if self.MT.all_rows_displayed:
|
4025
|
+
return
|
4006
4026
|
if isinstance(rows, int):
|
4007
4027
|
rows = [rows]
|
4008
4028
|
rhs = self.MT.get_row_heights()
|
@@ -4028,7 +4048,10 @@ class Sheet(tk.Frame):
|
|
4028
4048
|
|
4029
4049
|
@all_rows.setter
|
4030
4050
|
def all_rows(self, a: bool) -> Sheet:
|
4031
|
-
self.MT.
|
4051
|
+
self.MT.display_rows(
|
4052
|
+
rows=None,
|
4053
|
+
all_rows_displayed=a,
|
4054
|
+
)
|
4032
4055
|
return self
|
4033
4056
|
|
4034
4057
|
@property
|
@@ -4037,8 +4060,8 @@ class Sheet(tk.Frame):
|
|
4037
4060
|
|
4038
4061
|
@displayed_rows.setter
|
4039
4062
|
def displayed_rows(self, rows: list[int]) -> Sheet:
|
4040
|
-
self.display_rows(rows=rows, reset_row_positions=
|
4041
|
-
return self
|
4063
|
+
self.display_rows(rows=rows, reset_row_positions=True, redraw=False)
|
4064
|
+
return self.set_refresh_timer()
|
4042
4065
|
|
4043
4066
|
# Hiding Sheet Elements
|
4044
4067
|
|
@@ -4688,7 +4711,7 @@ class Sheet(tk.Frame):
|
|
4688
4711
|
self.RI.tree[iid].text = row[text_column]
|
4689
4712
|
else:
|
4690
4713
|
self.RI.tree[iid] = Node(row[text_column], iid, "")
|
4691
|
-
if safety and (iid == pid or self.RI.
|
4714
|
+
if safety and (iid == pid or self.RI.build_pid_causes_recursive_loop(iid, pid)):
|
4692
4715
|
row[parent_column] = ""
|
4693
4716
|
pid = ""
|
4694
4717
|
if pid:
|
@@ -4747,7 +4770,7 @@ class Sheet(tk.Frame):
|
|
4747
4770
|
Closes everything else
|
4748
4771
|
"""
|
4749
4772
|
self.hide_rows(
|
4750
|
-
|
4773
|
+
rows={rn for rn in self.MT.displayed_rows if self.MT._row_index[rn].parent},
|
4751
4774
|
redraw=False,
|
4752
4775
|
deselect_all=False,
|
4753
4776
|
data_indexes=True,
|
@@ -4768,13 +4791,15 @@ class Sheet(tk.Frame):
|
|
4768
4791
|
"""
|
4769
4792
|
to_open = []
|
4770
4793
|
disp_set = set(self.MT.displayed_rows)
|
4771
|
-
|
4772
|
-
|
4794
|
+
tree = self.RI.tree
|
4795
|
+
rns = self.RI.tree_rns
|
4796
|
+
open_ids = self.RI.tree_open_ids
|
4797
|
+
descendants = self.RI.get_iid_descendants
|
4773
4798
|
for item in filter(items.__contains__, self.get_children()):
|
4774
|
-
if
|
4775
|
-
|
4776
|
-
if
|
4777
|
-
to_disp = [
|
4799
|
+
if tree[item].children:
|
4800
|
+
open_ids.add(item)
|
4801
|
+
if rns[item] in disp_set:
|
4802
|
+
to_disp = [rns[did] for did in descendants(item, check_open=True)]
|
4778
4803
|
for i in to_disp:
|
4779
4804
|
disp_set.add(i)
|
4780
4805
|
to_open.extend(to_disp)
|
@@ -4921,7 +4946,7 @@ class Sheet(tk.Frame):
|
|
4921
4946
|
self.RI.tree_open_ids.add(item)
|
4922
4947
|
if self.item_displayed(item):
|
4923
4948
|
self.show_rows(
|
4924
|
-
rows=(self.RI.tree_rns
|
4949
|
+
rows=map(self.RI.tree_rns.__getitem__, self.RI.get_iid_descendants(item, check_open=True)),
|
4925
4950
|
redraw=False,
|
4926
4951
|
deselect_all=False,
|
4927
4952
|
)
|
@@ -4929,7 +4954,9 @@ class Sheet(tk.Frame):
|
|
4929
4954
|
self.RI.tree_open_ids.discard(item)
|
4930
4955
|
if self.item_displayed(item):
|
4931
4956
|
self.hide_rows(
|
4932
|
-
rows=
|
4957
|
+
rows=set(
|
4958
|
+
map(self.RI.tree_rns.__getitem__, self.RI.get_iid_descendants(item, check_open=True))
|
4959
|
+
),
|
4933
4960
|
redraw=False,
|
4934
4961
|
deselect_all=False,
|
4935
4962
|
data_indexes=True,
|
@@ -5014,7 +5041,8 @@ class Sheet(tk.Frame):
|
|
5014
5041
|
def move(self, item: str, parent: str, index: int | None = None) -> Sheet:
|
5015
5042
|
"""
|
5016
5043
|
Moves item to be under parent as child at index
|
5017
|
-
'parent' can be empty
|
5044
|
+
'parent' can be an empty str which will put the item at top level
|
5045
|
+
Performance is not great
|
5018
5046
|
"""
|
5019
5047
|
if (item := item.lower()) and item not in self.RI.tree:
|
5020
5048
|
raise ValueError(f"Item '{item}' does not exist.")
|
@@ -5023,25 +5051,61 @@ class Sheet(tk.Frame):
|
|
5023
5051
|
mapping = {}
|
5024
5052
|
to_show = []
|
5025
5053
|
item_node = self.RI.tree[item]
|
5054
|
+
item_r = self.RI.tree_rns[item]
|
5026
5055
|
if parent:
|
5027
|
-
if self.RI.
|
5056
|
+
if self.RI.move_pid_causes_recursive_loop(item, parent):
|
5028
5057
|
raise ValueError(f"iid '{item}' causes a recursive loop with parent '{parent}'.")
|
5029
5058
|
parent_node = self.RI.tree[parent]
|
5030
5059
|
if parent_node.children:
|
5031
5060
|
if index is None or index >= len(parent_node.children):
|
5032
|
-
index = len(parent_node.children)
|
5033
|
-
|
5034
|
-
|
5035
|
-
|
5036
|
-
|
5037
|
-
|
5038
|
-
|
5061
|
+
index = len(parent_node.children)
|
5062
|
+
new_r = self.RI.tree_rns[parent] + sum(1 for _ in self.RI.get_iid_descendants(parent))
|
5063
|
+
# new parent has children
|
5064
|
+
# index is on end
|
5065
|
+
# item row is less than move to row
|
5066
|
+
if item_r < new_r:
|
5067
|
+
r_ctr = new_r - sum(1 for _ in self.RI.get_iid_descendants(item))
|
5068
|
+
|
5069
|
+
# new parent has children
|
5070
|
+
# index is on end
|
5071
|
+
# item row is greater than move to row
|
5072
|
+
else:
|
5073
|
+
r_ctr = new_r + 1
|
5039
5074
|
else:
|
5040
|
-
|
5075
|
+
new_r = self.RI.tree_rns[parent_node.children[index].iid]
|
5076
|
+
# new parent has children
|
5077
|
+
# index is not end
|
5078
|
+
# item row is less than move to row
|
5079
|
+
if item_r < new_r:
|
5080
|
+
if self.RI.items_parent(item) == parent:
|
5081
|
+
r_ctr = (
|
5082
|
+
new_r
|
5083
|
+
+ sum(1 for _ in self.RI.get_iid_descendants(parent_node.children[index].iid))
|
5084
|
+
- sum(1 for _ in self.RI.get_iid_descendants(item))
|
5085
|
+
)
|
5086
|
+
else:
|
5087
|
+
r_ctr = new_r - sum(1 for _ in self.RI.get_iid_descendants(item)) - 1
|
5088
|
+
|
5089
|
+
# new parent has children
|
5090
|
+
# index is not end
|
5091
|
+
# item row is greater than move to row
|
5092
|
+
else:
|
5093
|
+
r_ctr = new_r
|
5041
5094
|
else:
|
5042
|
-
|
5043
|
-
|
5044
|
-
|
5095
|
+
index = 0
|
5096
|
+
new_r = self.RI.tree_rns[parent_node.iid]
|
5097
|
+
|
5098
|
+
# new parent doesn't have children
|
5099
|
+
# index always start
|
5100
|
+
# item row is less than move to row
|
5101
|
+
if item_r < new_r:
|
5102
|
+
r_ctr = new_r - sum(1 for _ in self.RI.get_iid_descendants(item))
|
5103
|
+
|
5104
|
+
# new parent doesn't have children
|
5105
|
+
# index always start
|
5106
|
+
# item row is greater than move to row
|
5107
|
+
else:
|
5108
|
+
r_ctr = new_r + 1
|
5045
5109
|
mapping[item_r] = r_ctr
|
5046
5110
|
if parent in self.RI.tree_open_ids and self.item_displayed(parent):
|
5047
5111
|
to_show.append(r_ctr)
|
@@ -5064,11 +5128,12 @@ class Sheet(tk.Frame):
|
|
5064
5128
|
else:
|
5065
5129
|
if (new_r := self.top_index_row(index)) is None:
|
5066
5130
|
new_r = self.top_index_row((sum(1 for _ in self.RI.gen_top_nodes()) - 1))
|
5067
|
-
item_r = self.RI.tree_rns[item]
|
5068
5131
|
if item_r < new_r:
|
5069
|
-
|
5070
|
-
|
5071
|
-
|
5132
|
+
r_ctr = (
|
5133
|
+
new_r
|
5134
|
+
+ sum(1 for _ in self.RI.get_iid_descendants(self.rowitem(new_r, data_index=True)))
|
5135
|
+
- sum(1 for _ in self.RI.get_iid_descendants(item))
|
5136
|
+
)
|
5072
5137
|
else:
|
5073
5138
|
r_ctr = new_r
|
5074
5139
|
mapping[item_r] = r_ctr
|
@@ -5106,7 +5171,8 @@ class Sheet(tk.Frame):
|
|
5106
5171
|
if (item := item.lower()) not in self.RI.tree:
|
5107
5172
|
raise ValueError(f"Item '{item}' does not exist.")
|
5108
5173
|
if not self.RI.tree[item].parent:
|
5109
|
-
|
5174
|
+
find_node = self.RI.tree[item]
|
5175
|
+
return next(index for index, node in enumerate(self.RI.gen_top_nodes()) if node == find_node)
|
5110
5176
|
return self.RI.tree[item].parent.children.index(self.RI.tree[item])
|
5111
5177
|
|
5112
5178
|
def item_displayed(self, item: str) -> bool:
|
@@ -5128,8 +5194,11 @@ class Sheet(tk.Frame):
|
|
5128
5194
|
if (item := item.lower()) not in self.RI.tree:
|
5129
5195
|
raise ValueError(f"Item '{item}' does not exist.")
|
5130
5196
|
if self.RI.tree[item].parent:
|
5131
|
-
|
5132
|
-
self.item
|
5197
|
+
self.show_rows(
|
5198
|
+
rows=self._tree_open(list(self.RI.get_iid_ancestors(item))),
|
5199
|
+
redraw=False,
|
5200
|
+
deselect_all=False,
|
5201
|
+
)
|
5133
5202
|
return self.set_refresh_timer(redraw)
|
5134
5203
|
|
5135
5204
|
def scroll_to_item(self, item: str, redraw=False) -> Sheet:
|
@@ -5151,14 +5220,15 @@ class Sheet(tk.Frame):
|
|
5151
5220
|
Get currently selected item ids
|
5152
5221
|
"""
|
5153
5222
|
return [
|
5154
|
-
self.MT._row_index[self.
|
5155
|
-
for rn in self.get_selected_rows(get_cells_as_rows=cells)
|
5223
|
+
self.MT._row_index[self.MT.displayed_rows[rn]].iid for rn in self.get_selected_rows(get_cells_as_rows=cells)
|
5156
5224
|
]
|
5157
5225
|
|
5158
5226
|
def selection_set(self, *items, redraw: bool = True) -> Sheet:
|
5159
5227
|
if any(item.lower() in self.RI.tree for item in unpack(items)):
|
5160
|
-
self.
|
5228
|
+
boxes_to_hide = tuple(self.MT.selection_boxes)
|
5161
5229
|
self.selection_add(*items, redraw=False)
|
5230
|
+
for iid in boxes_to_hide:
|
5231
|
+
self.MT.hide_selection_box(iid)
|
5162
5232
|
return self.set_refresh_timer(redraw)
|
5163
5233
|
|
5164
5234
|
def selection_add(self, *items, redraw: bool = True) -> Sheet:
|
@@ -5220,7 +5290,7 @@ class Sheet(tk.Frame):
|
|
5220
5290
|
|
5221
5291
|
# Functions not in docs
|
5222
5292
|
|
5223
|
-
def event_generate(self, *args, **kwargs):
|
5293
|
+
def event_generate(self, *args, **kwargs) -> None:
|
5224
5294
|
self.MT.event_generate(*args, **kwargs)
|
5225
5295
|
|
5226
5296
|
def emit_event(
|
@@ -6226,13 +6296,7 @@ class Sheet(tk.Frame):
|
|
6226
6296
|
) -> Sheet:
|
6227
6297
|
kwargs = get_dropdown_kwargs(*args, **kwargs)
|
6228
6298
|
d = get_dropdown_dict(**kwargs)
|
6229
|
-
if kwargs["set_value"] is None
|
6230
|
-
if kwargs["values"] and (v := self.MT.get_cell_data(r, c)) not in kwargs["values"]:
|
6231
|
-
v = kwargs["values"][0]
|
6232
|
-
else:
|
6233
|
-
v == ""
|
6234
|
-
else:
|
6235
|
-
v = kwargs["set_value"]
|
6299
|
+
v = kwargs["set_value"] if kwargs["set_value"] is not None else kwargs["values"][0] if kwargs["values"] else ""
|
6236
6300
|
if isinstance(r, str) and r.lower() == "all" and isinstance(c, int):
|
6237
6301
|
for r_ in range(self.MT.total_data_rows()):
|
6238
6302
|
self._create_dropdown(r_, c, v, d)
|
@@ -163,17 +163,16 @@ class TopLeftRectangle(tk.Canvas):
|
|
163
163
|
recreate_selection_boxes: bool = True,
|
164
164
|
) -> None:
|
165
165
|
try:
|
166
|
-
|
167
|
-
if new_h is None:
|
168
|
-
h = self.winfo_height()
|
169
|
-
if new_w is None:
|
170
|
-
w = self.winfo_width()
|
171
|
-
if new_w:
|
172
|
-
self.config(width=new_w)
|
173
|
-
w = new_w
|
174
|
-
if new_h:
|
175
|
-
self.config(height=new_h)
|
166
|
+
if isinstance(new_h, int):
|
176
167
|
h = new_h
|
168
|
+
self.config(height=h)
|
169
|
+
else:
|
170
|
+
h = self.CH.current_height
|
171
|
+
if isinstance(new_w, int):
|
172
|
+
w = new_w
|
173
|
+
self.config(width=w)
|
174
|
+
else:
|
175
|
+
w = self.RI.current_width
|
177
176
|
except Exception:
|
178
177
|
return
|
179
178
|
self.coords(self.rw_box, 0, h - 5, w, h)
|
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
|