tksheet 7.5.5__py3-none-any.whl → 7.5.8__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 +1 -1
- tksheet/column_headers.py +230 -87
- tksheet/constants.py +1 -0
- tksheet/find_window.py +4 -4
- tksheet/formatters.py +4 -2
- tksheet/functions.py +91 -35
- tksheet/main_table.py +374 -643
- tksheet/menus.py +494 -0
- tksheet/other_classes.py +3 -0
- tksheet/row_index.py +235 -97
- tksheet/sheet.py +99 -39
- tksheet/sheet_options.py +5 -1
- tksheet/tksheet_types.py +1 -0
- tksheet/tooltip.py +335 -0
- {tksheet-7.5.5.dist-info → tksheet-7.5.8.dist-info}/METADATA +1 -1
- tksheet-7.5.8.dist-info/RECORD +24 -0
- {tksheet-7.5.5.dist-info → tksheet-7.5.8.dist-info}/WHEEL +1 -1
- tksheet-7.5.5.dist-info/RECORD +0 -22
- {tksheet-7.5.5.dist-info → tksheet-7.5.8.dist-info}/licenses/LICENSE.txt +0 -0
- {tksheet-7.5.5.dist-info → tksheet-7.5.8.dist-info}/top_level.txt +0 -0
tksheet/row_index.py
CHANGED
@@ -24,6 +24,7 @@ from .functions import (
|
|
24
24
|
event_dict,
|
25
25
|
event_has_char_key,
|
26
26
|
event_opens_dropdown_or_checkbox,
|
27
|
+
get_bg_fg,
|
27
28
|
get_menu_kwargs,
|
28
29
|
get_n2a,
|
29
30
|
get_new_indexes,
|
@@ -33,15 +34,20 @@ from .functions import (
|
|
33
34
|
new_tk_event,
|
34
35
|
num2alpha,
|
35
36
|
push_displayed,
|
37
|
+
recursive_bind,
|
36
38
|
rounded_box_coords,
|
39
|
+
safe_copy,
|
37
40
|
stored_event_dict,
|
38
41
|
try_b_index,
|
39
42
|
try_binding,
|
43
|
+
widget_descendants,
|
40
44
|
wrap_text,
|
41
45
|
)
|
46
|
+
from .menus import build_empty_rc_menu, build_index_rc_menu
|
42
47
|
from .other_classes import DraggedRowColumn, DropdownStorage, EventDataDict, Node, TextEditorStorage
|
43
48
|
from .sorting import sort_columns_by_row, sort_row
|
44
49
|
from .text_editor import TextEditor
|
50
|
+
from .tooltip import Tooltip
|
45
51
|
|
46
52
|
|
47
53
|
class RowIndex(tk.Canvas):
|
@@ -56,6 +62,18 @@ class RowIndex(tk.Canvas):
|
|
56
62
|
self.MT = None # is set from within MainTable() __init__
|
57
63
|
self.CH = None # is set from within MainTable() __init__
|
58
64
|
self.TL = None # is set from within TopLeftRectangle() __init__
|
65
|
+
self.tooltip = Tooltip(
|
66
|
+
**{
|
67
|
+
"parent": self,
|
68
|
+
"sheet_ops": self.ops,
|
69
|
+
"menu_kwargs": get_menu_kwargs(self.ops),
|
70
|
+
**get_bg_fg(self.ops),
|
71
|
+
"scrollbar_style": f"Sheet{self.PAR.unique_id}.Vertical.TScrollbar",
|
72
|
+
}
|
73
|
+
)
|
74
|
+
self.tooltip_widgets = widget_descendants(self.tooltip)
|
75
|
+
self.tooltip_coords, self.tooltip_after_id, self.tooltip_showing = None, None, False
|
76
|
+
recursive_bind(self.tooltip, "<Leave>", self.close_tooltip_save)
|
59
77
|
self.current_cursor = ""
|
60
78
|
self.new_iid_ctr = -1
|
61
79
|
self.current_width = None
|
@@ -109,7 +127,7 @@ class RowIndex(tk.Canvas):
|
|
109
127
|
self.disp_dropdown = {}
|
110
128
|
self.disp_checkbox = {}
|
111
129
|
self.disp_tree_arrow = {}
|
112
|
-
self.
|
130
|
+
self.disp_corners = set()
|
113
131
|
self.hidd_text = {}
|
114
132
|
self.hidd_high = {}
|
115
133
|
self.hidd_grid = {}
|
@@ -119,7 +137,7 @@ class RowIndex(tk.Canvas):
|
|
119
137
|
self.hidd_dropdown = {}
|
120
138
|
self.hidd_checkbox = {}
|
121
139
|
self.hidd_tree_arrow = {}
|
122
|
-
self.
|
140
|
+
self.hidd_corners = set()
|
123
141
|
|
124
142
|
self.align = kwargs["row_index_align"]
|
125
143
|
|
@@ -169,15 +187,17 @@ class RowIndex(tk.Canvas):
|
|
169
187
|
popup_menu = None
|
170
188
|
if self.MT.identify_row(y=event.y, allow_end=False) is None:
|
171
189
|
self.MT.deselect("all")
|
172
|
-
r = len(self.MT.
|
190
|
+
r = len(self.MT.row_positions) - 1
|
173
191
|
if self.MT.rc_popup_menus_enabled:
|
174
192
|
popup_menu = self.MT.empty_rc_popup_menu
|
193
|
+
build_empty_rc_menu(self.MT, popup_menu)
|
175
194
|
elif self.row_selection_enabled and not self.currently_resizing_width and not self.currently_resizing_height:
|
176
195
|
r = self.MT.identify_row(y=event.y)
|
177
196
|
if r < len(self.MT.row_positions) - 1:
|
178
197
|
if self.MT.row_selected(r):
|
179
198
|
if self.MT.rc_popup_menus_enabled:
|
180
199
|
popup_menu = self.ri_rc_popup_menu
|
200
|
+
build_index_rc_menu(self.MT, popup_menu, r)
|
181
201
|
else:
|
182
202
|
if self.MT.single_selection_enabled and self.MT.rc_select_enabled:
|
183
203
|
self.select_row(r, redraw=True)
|
@@ -185,11 +205,10 @@ class RowIndex(tk.Canvas):
|
|
185
205
|
self.toggle_select_row(r, redraw=True)
|
186
206
|
if self.MT.rc_popup_menus_enabled:
|
187
207
|
popup_menu = self.ri_rc_popup_menu
|
208
|
+
build_index_rc_menu(self.MT, popup_menu, r)
|
188
209
|
try_binding(self.extra_rc_func, event)
|
189
210
|
if popup_menu is not None:
|
190
211
|
self.popup_menu_loc = r
|
191
|
-
self.MT.popup_menu_disable_edit_if_readonly(popup_menu)
|
192
|
-
self.MT.popup_menu_disable_undo_redo(popup_menu)
|
193
212
|
popup_menu.tk_popup(event.x_root, event.y_root)
|
194
213
|
|
195
214
|
def ctrl_b1_press(self, event: Any) -> None:
|
@@ -911,7 +930,7 @@ class RowIndex(tk.Canvas):
|
|
911
930
|
event_data = self.MT.new_event_dict("edit_table")
|
912
931
|
try_binding(self.MT.extra_begin_sort_cells_func, event_data)
|
913
932
|
if key is None:
|
914
|
-
key = self.
|
933
|
+
key = self.ops.sort_key
|
915
934
|
for r in rows:
|
916
935
|
datarn = self.MT.datarn(r)
|
917
936
|
for c, val in enumerate(sort_row(self.MT.data[datarn], reverse=reverse, key=key)):
|
@@ -957,7 +976,7 @@ class RowIndex(tk.Canvas):
|
|
957
976
|
row = self.MT.datarn(self.MT.selected.row)
|
958
977
|
if try_binding(self.ri_extra_begin_sort_cols_func, event_data, "begin_move_columns"):
|
959
978
|
if key is None:
|
960
|
-
key = self.
|
979
|
+
key = self.ops.sort_key
|
961
980
|
sorted_indices, data_new_idxs = sort_columns_by_row(self.MT.data, row=row, reverse=reverse, key=key)
|
962
981
|
disp_new_idxs = {}
|
963
982
|
if self.MT.all_columns_displayed:
|
@@ -1295,44 +1314,60 @@ class RowIndex(tk.Canvas):
|
|
1295
1314
|
redrawn = False
|
1296
1315
|
kwargs = self.get_cell_kwargs(datarn, key="highlight")
|
1297
1316
|
if kwargs:
|
1298
|
-
|
1299
|
-
if
|
1300
|
-
|
1317
|
+
high_bg = kwargs[0]
|
1318
|
+
if high_bg and not high_bg.startswith("#"):
|
1319
|
+
high_bg = color_map[high_bg]
|
1301
1320
|
if "rows" in selections and r in selections["rows"]:
|
1302
1321
|
txtfg = (
|
1303
1322
|
self.ops.index_selected_rows_fg
|
1304
1323
|
if kwargs[1] is None or self.ops.display_selected_fg_over_highlights
|
1305
1324
|
else kwargs[1]
|
1306
1325
|
)
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1326
|
+
redrawn = self.redraw_highlight(
|
1327
|
+
0,
|
1328
|
+
fr + 1,
|
1329
|
+
self.current_width - 1,
|
1330
|
+
sr,
|
1331
|
+
fill=self.ops.index_selected_rows_bg
|
1332
|
+
if high_bg is None
|
1333
|
+
else (
|
1334
|
+
f"#{int((int(high_bg[1:3], 16) + int(sel_rows_bg[1:3], 16)) / 2):02X}"
|
1335
|
+
+ f"{int((int(high_bg[3:5], 16) + int(sel_rows_bg[3:5], 16)) / 2):02X}"
|
1336
|
+
+ f"{int((int(high_bg[5:], 16) + int(sel_rows_bg[5:], 16)) / 2):02X}"
|
1337
|
+
),
|
1338
|
+
outline=self.ops.index_fg if has_dd and self.ops.show_dropdown_borders else "",
|
1339
|
+
)
|
1313
1340
|
elif "cells" in selections and r in selections["cells"]:
|
1314
1341
|
txtfg = (
|
1315
1342
|
self.ops.index_selected_cells_fg
|
1316
1343
|
if kwargs[1] is None or self.ops.display_selected_fg_over_highlights
|
1317
1344
|
else kwargs[1]
|
1318
1345
|
)
|
1319
|
-
if fill:
|
1320
|
-
fill = (
|
1321
|
-
f"#{int((int(fill[1:3], 16) + int(sel_cells_bg[1:3], 16)) / 2):02X}"
|
1322
|
-
+ f"{int((int(fill[3:5], 16) + int(sel_cells_bg[3:5], 16)) / 2):02X}"
|
1323
|
-
+ f"{int((int(fill[5:], 16) + int(sel_cells_bg[5:], 16)) / 2):02X}"
|
1324
|
-
)
|
1325
|
-
else:
|
1326
|
-
txtfg = self.ops.index_fg if kwargs[1] is None else kwargs[1]
|
1327
|
-
if fill:
|
1328
1346
|
redrawn = self.redraw_highlight(
|
1329
1347
|
0,
|
1330
1348
|
fr + 1,
|
1331
1349
|
self.current_width - 1,
|
1332
1350
|
sr,
|
1333
|
-
fill=
|
1351
|
+
fill=self.ops.index_selected_cells_bg
|
1352
|
+
if high_bg is None
|
1353
|
+
else (
|
1354
|
+
f"#{int((int(high_bg[1:3], 16) + int(sel_cells_bg[1:3], 16)) / 2):02X}"
|
1355
|
+
+ f"{int((int(high_bg[3:5], 16) + int(sel_cells_bg[3:5], 16)) / 2):02X}"
|
1356
|
+
+ f"{int((int(high_bg[5:], 16) + int(sel_cells_bg[5:], 16)) / 2):02X}"
|
1357
|
+
),
|
1334
1358
|
outline=self.ops.index_fg if has_dd and self.ops.show_dropdown_borders else "",
|
1335
1359
|
)
|
1360
|
+
else:
|
1361
|
+
txtfg = self.ops.index_fg if kwargs[1] is None else kwargs[1]
|
1362
|
+
if high_bg:
|
1363
|
+
redrawn = self.redraw_highlight(
|
1364
|
+
0,
|
1365
|
+
fr + 1,
|
1366
|
+
self.current_width - 1,
|
1367
|
+
sr,
|
1368
|
+
fill=high_bg,
|
1369
|
+
outline=self.ops.index_fg if has_dd and self.ops.show_dropdown_borders else "",
|
1370
|
+
)
|
1336
1371
|
tree_arrow_fg = txtfg
|
1337
1372
|
elif not kwargs:
|
1338
1373
|
if "rows" in selections and r in selections["rows"]:
|
@@ -1614,6 +1649,17 @@ class RowIndex(tk.Canvas):
|
|
1614
1649
|
self.MT.char_widths[self.index_font][c] = wd
|
1615
1650
|
return wd
|
1616
1651
|
|
1652
|
+
def redraw_corner(self, x: float, y: float) -> None:
|
1653
|
+
if self.hidd_corners:
|
1654
|
+
iid = self.hidd_corners.pop()
|
1655
|
+
self.coords(iid, x - 10, y, x, y, x, y + 10)
|
1656
|
+
self.itemconfig(iid, fill=self.ops.index_grid_fg, state="normal")
|
1657
|
+
self.disp_corners.add(iid)
|
1658
|
+
else:
|
1659
|
+
self.disp_corners.add(
|
1660
|
+
self.create_polygon(x - 10, y, x, y, x, y + 10, fill=self.ops.index_grid_fg, tags="lift")
|
1661
|
+
)
|
1662
|
+
|
1617
1663
|
def redraw_grid_and_text(
|
1618
1664
|
self,
|
1619
1665
|
last_row_line_pos: float,
|
@@ -1641,6 +1687,8 @@ class RowIndex(tk.Canvas):
|
|
1641
1687
|
self.disp_checkbox = {}
|
1642
1688
|
self.hidd_tree_arrow.update(self.disp_tree_arrow)
|
1643
1689
|
self.disp_tree_arrow = {}
|
1690
|
+
self.hidd_corners.update(self.disp_corners)
|
1691
|
+
self.disp_corners = set()
|
1644
1692
|
self.visible_row_dividers = {}
|
1645
1693
|
self.row_width_resize_bbox = (
|
1646
1694
|
self.current_width - 2,
|
@@ -1692,6 +1740,7 @@ class RowIndex(tk.Canvas):
|
|
1692
1740
|
dd_coords = self.dropdown.get_coords()
|
1693
1741
|
treeview = self.ops.treeview
|
1694
1742
|
wrap = self.ops.index_wrap
|
1743
|
+
note_corners = self.ops.note_corners
|
1695
1744
|
for r in range(text_start_row, text_end_row):
|
1696
1745
|
rtopgridln = self.MT.row_positions[r]
|
1697
1746
|
rbotgridln = self.MT.row_positions[r + 1]
|
@@ -1787,6 +1836,10 @@ class RowIndex(tk.Canvas):
|
|
1787
1836
|
open_=self.MT._row_index[datarn].iid in self.tree_open_ids,
|
1788
1837
|
level=level,
|
1789
1838
|
)
|
1839
|
+
|
1840
|
+
if note_corners and max_width > 5 and datarn in self.cell_options and "note" in self.cell_options[datarn]:
|
1841
|
+
self.redraw_corner(self.current_width, rtopgridln)
|
1842
|
+
|
1790
1843
|
if max_width <= 1:
|
1791
1844
|
continue
|
1792
1845
|
text = self.cell_str(datarn, fix=False)
|
@@ -1814,6 +1867,7 @@ class RowIndex(tk.Canvas):
|
|
1814
1867
|
fill=fill,
|
1815
1868
|
font=font,
|
1816
1869
|
anchor=align,
|
1870
|
+
tags=("lift", "t", f"{r}"),
|
1817
1871
|
)
|
1818
1872
|
else:
|
1819
1873
|
self.itemconfig(
|
@@ -1823,6 +1877,7 @@ class RowIndex(tk.Canvas):
|
|
1823
1877
|
font=font,
|
1824
1878
|
anchor=align,
|
1825
1879
|
state="normal",
|
1880
|
+
tags=("lift", "t", f"{r}"),
|
1826
1881
|
)
|
1827
1882
|
else:
|
1828
1883
|
iid = self.create_text(
|
@@ -1832,7 +1887,7 @@ class RowIndex(tk.Canvas):
|
|
1832
1887
|
fill=fill,
|
1833
1888
|
font=font,
|
1834
1889
|
anchor=align,
|
1835
|
-
|
1890
|
+
tags=("lift", "t", f"{r}"),
|
1836
1891
|
)
|
1837
1892
|
self.disp_text[iid] = True
|
1838
1893
|
else:
|
@@ -1847,6 +1902,7 @@ class RowIndex(tk.Canvas):
|
|
1847
1902
|
fill=fill,
|
1848
1903
|
font=font,
|
1849
1904
|
anchor=align,
|
1905
|
+
tags=("lift", "t", f"{r}"),
|
1850
1906
|
)
|
1851
1907
|
else:
|
1852
1908
|
self.itemconfig(
|
@@ -1856,6 +1912,7 @@ class RowIndex(tk.Canvas):
|
|
1856
1912
|
font=font,
|
1857
1913
|
anchor=align,
|
1858
1914
|
state="normal",
|
1915
|
+
tags=("lift", "t", f"{r}"),
|
1859
1916
|
)
|
1860
1917
|
else:
|
1861
1918
|
iid = self.create_text(
|
@@ -1865,7 +1922,7 @@ class RowIndex(tk.Canvas):
|
|
1865
1922
|
fill=fill,
|
1866
1923
|
font=font,
|
1867
1924
|
anchor=align,
|
1868
|
-
|
1925
|
+
tags=("lift", "t", f"{r}"),
|
1869
1926
|
)
|
1870
1927
|
self.disp_text[iid] = True
|
1871
1928
|
draw_y += self.MT.header_txt_height
|
@@ -1882,11 +1939,115 @@ class RowIndex(tk.Canvas):
|
|
1882
1939
|
if showing:
|
1883
1940
|
self.itemconfig(iid, state="hidden")
|
1884
1941
|
dct[iid] = False
|
1942
|
+
for iid in self.hidd_corners:
|
1943
|
+
self.itemconfig(iid, state="hidden")
|
1885
1944
|
self.tag_raise("lift")
|
1886
1945
|
if self.disp_resize_lines:
|
1887
1946
|
self.tag_raise("rh")
|
1947
|
+
self.tag_bind("t", "<Enter>", self.enter_text)
|
1948
|
+
self.tag_bind("t", "<Leave>", self.leave_text)
|
1888
1949
|
return True
|
1889
1950
|
|
1951
|
+
def enter_text(self, event: tk.Event | None = None) -> None:
|
1952
|
+
if self.text_editor.open or self.dropdown.open:
|
1953
|
+
return
|
1954
|
+
can_x, can_y = self.canvasx(event.x), self.canvasy(event.y)
|
1955
|
+
for i in self.find_overlapping(can_x - 1, can_y - 1, can_x + 1, can_y + 1):
|
1956
|
+
try:
|
1957
|
+
if (coords := self.gettags(i)[2]) == self.tooltip_coords:
|
1958
|
+
return
|
1959
|
+
self.tooltip_coords = coords
|
1960
|
+
self.tooltip_last_x, self.tooltip_last_y = self.winfo_pointerx(), self.winfo_pointery()
|
1961
|
+
self.start_tooltip_timer()
|
1962
|
+
return
|
1963
|
+
except Exception:
|
1964
|
+
continue
|
1965
|
+
|
1966
|
+
def leave_text(self, event: tk.Event | None = None) -> None:
|
1967
|
+
if self.tooltip_after_id is not None:
|
1968
|
+
self.after_cancel(self.tooltip_after_id)
|
1969
|
+
self.tooltip_after_id = None
|
1970
|
+
if self.tooltip_showing:
|
1971
|
+
if self.winfo_containing(self.winfo_pointerx(), self.winfo_pointery()) not in self.tooltip_widgets:
|
1972
|
+
self.close_tooltip_save()
|
1973
|
+
else:
|
1974
|
+
self.tooltip_coords = None
|
1975
|
+
|
1976
|
+
def start_tooltip_timer(self) -> None:
|
1977
|
+
self.tooltip_after_id = self.after(1000, self.check_and_show_tooltip)
|
1978
|
+
|
1979
|
+
def check_and_show_tooltip(self, event: tk.Event | None = None) -> None:
|
1980
|
+
current_x, current_y = self.winfo_pointerx(), self.winfo_pointery()
|
1981
|
+
if current_x < 0 or current_y < 0:
|
1982
|
+
return
|
1983
|
+
if abs(current_x - self.tooltip_last_x) <= 1 and abs(current_y - self.tooltip_last_y) <= 1:
|
1984
|
+
self.show_tooltip()
|
1985
|
+
else:
|
1986
|
+
self.tooltip_last_x, self.tooltip_last_y = current_x, current_y
|
1987
|
+
self.tooltip_after_id = self.after(400, self.check_and_show_tooltip)
|
1988
|
+
|
1989
|
+
def hide_tooltip(self) -> None:
|
1990
|
+
self.tooltip.withdraw()
|
1991
|
+
self.tooltip_showing, self.tooltip_coords = False, None
|
1992
|
+
|
1993
|
+
def show_tooltip(self) -> None:
|
1994
|
+
r = int(self.tooltip_coords)
|
1995
|
+
datarn = self.MT.datarn(r)
|
1996
|
+
kws = self.get_cell_kwargs(datarn, key="note")
|
1997
|
+
if not self.ops.tooltips and not kws and not self.ops.user_can_create_notes:
|
1998
|
+
return
|
1999
|
+
cell_readonly = self.get_cell_kwargs(datarn, "readonly") or not self.MT.index_edit_cell_enabled()
|
2000
|
+
if kws:
|
2001
|
+
note = kws["note"]
|
2002
|
+
note_readonly = kws["readonly"]
|
2003
|
+
elif self.ops.user_can_create_notes:
|
2004
|
+
note = ""
|
2005
|
+
note_readonly = bool(cell_readonly)
|
2006
|
+
else:
|
2007
|
+
note = None
|
2008
|
+
note_readonly = True
|
2009
|
+
self.tooltip.reset(
|
2010
|
+
**{
|
2011
|
+
"text": f"{self.get_cell_data(datarn, none_to_empty_str=True)}",
|
2012
|
+
"cell_readonly": cell_readonly,
|
2013
|
+
"note": note,
|
2014
|
+
"note_readonly": note_readonly,
|
2015
|
+
"row": r,
|
2016
|
+
"col": 0,
|
2017
|
+
"menu_kwargs": get_menu_kwargs(self.ops),
|
2018
|
+
**get_bg_fg(self.ops),
|
2019
|
+
"user_can_create_notes": self.ops.user_can_create_notes,
|
2020
|
+
"note_only": not self.ops.tooltips and isinstance(note, str),
|
2021
|
+
"width": self.ops.tooltip_width,
|
2022
|
+
"height": self.ops.tooltip_height,
|
2023
|
+
}
|
2024
|
+
)
|
2025
|
+
self.tooltip.set_position(self.tooltip_last_x - 4, self.tooltip_last_y - 4)
|
2026
|
+
self.tooltip_showing = True
|
2027
|
+
|
2028
|
+
def close_tooltip_save(self, event: tk.Event | None = None) -> None:
|
2029
|
+
widget = self.winfo_containing(self.winfo_pointerx(), self.winfo_pointery())
|
2030
|
+
if any(widget == tw for tw in self.tooltip_widgets):
|
2031
|
+
try:
|
2032
|
+
if self.tooltip.notebook.index("current") == 0:
|
2033
|
+
self.tooltip.content_text.focus_set()
|
2034
|
+
else:
|
2035
|
+
self.tooltip.note_text.focus_set()
|
2036
|
+
except Exception:
|
2037
|
+
self.tooltip.content_text.focus_set()
|
2038
|
+
return
|
2039
|
+
if not self.tooltip.cell_readonly:
|
2040
|
+
r, _, cell, note = self.tooltip.get()
|
2041
|
+
datarn = self.MT.datarn(r)
|
2042
|
+
event_data = self.new_single_edit_event(r, datarn, "??", self.get_cell_data(datarn), cell)
|
2043
|
+
self.do_single_edit(r, datarn, event_data, cell)
|
2044
|
+
if not self.tooltip.note_readonly:
|
2045
|
+
span = self.PAR.span(datarn).options(table=False, index=True)
|
2046
|
+
self.PAR.note(span, note=note if note else None, readonly=False)
|
2047
|
+
self.hide_tooltip()
|
2048
|
+
self.MT.refresh()
|
2049
|
+
self.focus_set()
|
2050
|
+
|
1890
2051
|
def get_redraw_selections(self, startr: int, endr: int) -> dict[str, set[int]]:
|
1891
2052
|
d = defaultdict(set)
|
1892
2053
|
for _, box in self.MT.get_selection_items():
|
@@ -2100,6 +2261,18 @@ class RowIndex(tk.Canvas):
|
|
2100
2261
|
self.itemconfig(self.text_editor.canvas_id, state="hidden")
|
2101
2262
|
self.text_editor.open = False
|
2102
2263
|
|
2264
|
+
def do_single_edit(self, r: int, datarn: int, event_data: EventDataDict, val):
|
2265
|
+
edited = False
|
2266
|
+
set_data = partial(self.set_cell_data_undo, r=r, datarn=datarn, check_input_valid=False)
|
2267
|
+
if self.MT.edit_validation_func:
|
2268
|
+
val = self.MT.edit_validation_func(event_data)
|
2269
|
+
if val is not None and self.input_valid_for_cell(datarn, val):
|
2270
|
+
edited = set_data(value=val)
|
2271
|
+
elif self.input_valid_for_cell(datarn, val):
|
2272
|
+
edited = set_data(value=val)
|
2273
|
+
if edited:
|
2274
|
+
try_binding(self.extra_end_edit_cell_func, event_data)
|
2275
|
+
|
2103
2276
|
# r is displayed row
|
2104
2277
|
def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
|
2105
2278
|
# checking if text editor should be closed or not
|
@@ -2122,33 +2295,8 @@ class RowIndex(tk.Canvas):
|
|
2122
2295
|
text_editor_value = self.text_editor.get()
|
2123
2296
|
r = self.text_editor.row
|
2124
2297
|
datarn = r if self.MT.all_rows_displayed else self.MT.displayed_rows[r]
|
2125
|
-
event_data =
|
2126
|
-
|
2127
|
-
sheet=self.PAR.name,
|
2128
|
-
widget=self,
|
2129
|
-
cells_index={datarn: self.get_cell_data(datarn)},
|
2130
|
-
key=event.keysym,
|
2131
|
-
value=text_editor_value,
|
2132
|
-
loc=r,
|
2133
|
-
row=r,
|
2134
|
-
boxes=self.MT.get_boxes(),
|
2135
|
-
selected=self.MT.selected,
|
2136
|
-
)
|
2137
|
-
edited = False
|
2138
|
-
set_data = partial(
|
2139
|
-
self.set_cell_data_undo,
|
2140
|
-
r=r,
|
2141
|
-
datarn=datarn,
|
2142
|
-
check_input_valid=False,
|
2143
|
-
)
|
2144
|
-
if self.MT.edit_validation_func:
|
2145
|
-
text_editor_value = self.MT.edit_validation_func(event_data)
|
2146
|
-
if text_editor_value is not None and self.input_valid_for_cell(datarn, text_editor_value):
|
2147
|
-
edited = set_data(value=text_editor_value)
|
2148
|
-
elif self.input_valid_for_cell(datarn, text_editor_value):
|
2149
|
-
edited = set_data(value=text_editor_value)
|
2150
|
-
if edited:
|
2151
|
-
try_binding(self.extra_end_edit_cell_func, event_data)
|
2298
|
+
event_data = self.new_single_edit_event(r, datarn, event.keysym, self.get_cell_data(datarn), text_editor_value)
|
2299
|
+
self.do_single_edit(r, datarn, event_data, text_editor_value)
|
2152
2300
|
self.MT.recreate_all_selection_boxes()
|
2153
2301
|
self.hide_text_editor_and_dropdown()
|
2154
2302
|
if event.keysym != "FocusOut":
|
@@ -2284,27 +2432,11 @@ class RowIndex(tk.Canvas):
|
|
2284
2432
|
self.MT.main_table_redraw_grid_and_text(redraw_header=False, redraw_row_index=True, redraw_table=False)
|
2285
2433
|
|
2286
2434
|
# r is displayed row
|
2287
|
-
def close_dropdown_window(
|
2288
|
-
self,
|
2289
|
-
r: int | None = None,
|
2290
|
-
selection: Any = None,
|
2291
|
-
redraw: bool = True,
|
2292
|
-
) -> None:
|
2435
|
+
def close_dropdown_window(self, r: int | None = None, selection: Any = None, redraw: bool = True) -> None:
|
2293
2436
|
if r is not None and selection is not None:
|
2294
2437
|
datarn = r if self.MT.all_rows_displayed else self.MT.displayed_rows[r]
|
2295
2438
|
kwargs = self.get_cell_kwargs(datarn, key="dropdown")
|
2296
|
-
event_data =
|
2297
|
-
name="end_edit_index",
|
2298
|
-
sheet=self.PAR.name,
|
2299
|
-
widget=self,
|
2300
|
-
cells_header={datarn: self.get_cell_data(datarn)},
|
2301
|
-
key="??",
|
2302
|
-
value=selection,
|
2303
|
-
loc=r,
|
2304
|
-
row=r,
|
2305
|
-
boxes=self.MT.get_boxes(),
|
2306
|
-
selected=self.MT.selected,
|
2307
|
-
)
|
2439
|
+
event_data = self.new_single_edit_event(r, datarn, "??", self.get_cell_data(datarn), selection)
|
2308
2440
|
try_binding(kwargs["select_function"], event_data)
|
2309
2441
|
selection = selection if not self.MT.edit_validation_func else self.MT.edit_validation_func(event_data)
|
2310
2442
|
if selection is not None:
|
@@ -2483,12 +2615,14 @@ class RowIndex(tk.Canvas):
|
|
2483
2615
|
return Node(text=iid, iid=iid, parent=self.get_row_parent(datarn))
|
2484
2616
|
if self.get_cell_kwargs(datarn, key="checkbox", cell=r_ops):
|
2485
2617
|
return False
|
2486
|
-
elif (
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2490
|
-
|
2491
|
-
|
2618
|
+
elif (kwargs := self.get_cell_kwargs(datarn, key="dropdown", cell=r_ops)) and kwargs["validate_input"]:
|
2619
|
+
if kwargs["default_value"] is None:
|
2620
|
+
if kwargs["values"]:
|
2621
|
+
return safe_copy(kwargs["values"][0])
|
2622
|
+
else:
|
2623
|
+
return ""
|
2624
|
+
else:
|
2625
|
+
return safe_copy(kwargs["default_value"])
|
2492
2626
|
else:
|
2493
2627
|
return ""
|
2494
2628
|
|
@@ -2539,18 +2673,7 @@ class RowIndex(tk.Canvas):
|
|
2539
2673
|
else:
|
2540
2674
|
value = False
|
2541
2675
|
self.set_cell_data_undo(r, datarn=datarn, value=value, cell_resize=False)
|
2542
|
-
event_data =
|
2543
|
-
name="end_edit_index",
|
2544
|
-
sheet=self.PAR.name,
|
2545
|
-
widget=self,
|
2546
|
-
cells_index={datarn: pre_edit_value},
|
2547
|
-
key="??",
|
2548
|
-
value=value,
|
2549
|
-
loc=r,
|
2550
|
-
row=r,
|
2551
|
-
boxes=self.MT.get_boxes(),
|
2552
|
-
selected=self.MT.selected,
|
2553
|
-
)
|
2676
|
+
event_data = self.new_single_edit_event(r, datarn, "??", pre_edit_value, value)
|
2554
2677
|
if kwargs["check_function"] is not None:
|
2555
2678
|
kwargs["check_function"](event_data)
|
2556
2679
|
try_binding(self.extra_end_edit_cell_func, event_data)
|
@@ -2563,6 +2686,21 @@ class RowIndex(tk.Canvas):
|
|
2563
2686
|
else:
|
2564
2687
|
return {}
|
2565
2688
|
|
2689
|
+
def new_single_edit_event(self, r: int, datarn: int, k: str, before_val: Any, after_val: Any) -> EventDataDict:
|
2690
|
+
return event_dict(
|
2691
|
+
name="end_edit_index",
|
2692
|
+
sheet=self.PAR.name,
|
2693
|
+
widget=self,
|
2694
|
+
cells_index={datarn: before_val},
|
2695
|
+
key=k,
|
2696
|
+
value=after_val,
|
2697
|
+
loc=r,
|
2698
|
+
row=r,
|
2699
|
+
boxes=self.MT.get_boxes(),
|
2700
|
+
selected=self.MT.selected,
|
2701
|
+
data={datarn: after_val},
|
2702
|
+
)
|
2703
|
+
|
2566
2704
|
# Treeview Mode
|
2567
2705
|
|
2568
2706
|
def tree_reset(self) -> None:
|
@@ -2711,14 +2849,14 @@ class RowIndex(tk.Canvas):
|
|
2711
2849
|
# determine insert row
|
2712
2850
|
insert_row = self.PAR._get_id_insert_row(move_to_index, new_parent)
|
2713
2851
|
else:
|
2852
|
+
# remove any descendants
|
2714
2853
|
iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2854
|
+
moved_rows = sorted(
|
2855
|
+
self.rns[iid]
|
2856
|
+
for iid in iids
|
2857
|
+
if not any(ancestor in iids for ancestor in self.get_iid_ancestors(iid))
|
2858
|
+
)
|
2720
2859
|
item = self.MT._row_index[moved_rows[0]].iid
|
2721
|
-
|
2722
2860
|
if isinstance(event_data.value, int):
|
2723
2861
|
if event_data.value >= len(self.MT.displayed_rows):
|
2724
2862
|
insert_row = len(self.MT._row_index)
|