tksheet 7.2.20__tar.gz → 7.2.22__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.20/tksheet.egg-info → tksheet-7.2.22}/PKG-INFO +2 -2
- {tksheet-7.2.20 → tksheet-7.2.22}/README.md +1 -1
- {tksheet-7.2.20 → tksheet-7.2.22}/pyproject.toml +1 -1
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/__init__.py +1 -1
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/column_headers.py +71 -56
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/functions.py +17 -14
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/main_table.py +182 -138
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/other_classes.py +19 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/row_index.py +64 -55
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/sheet.py +115 -17
- {tksheet-7.2.20 → tksheet-7.2.22/tksheet.egg-info}/PKG-INFO +2 -2
- {tksheet-7.2.20 → tksheet-7.2.22}/LICENSE.txt +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/setup.cfg +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/colors.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/formatters.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/sheet_options.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/text_editor.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/themes.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/top_left_rectangle.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/types.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet/vars.py +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.2.20 → tksheet-7.2.22}/tksheet.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tksheet
|
3
|
-
Version: 7.2.
|
3
|
+
Version: 7.2.22
|
4
4
|
Summary: Tkinter table / sheet widget
|
5
5
|
Author-email: ragardner <github@ragardner.simplelogin.com>
|
6
6
|
License: Copyright (c) 2019 ragardner and open source contributors
|
@@ -46,7 +46,7 @@ License-File: LICENSE.txt
|
|
46
46
|
|
47
47
|
# <div align="center">tksheet - python tkinter table widget</div>
|
48
48
|
|
49
|
-
[](https://pypi.python.org/pypi/tksheet/)  [](https://github.com/ragardner/tksheet/blob/master/LICENSE.txt)
|
49
|
+
[](https://pypi.python.org/pypi/tksheet/)  [](https://github.com/ragardner/tksheet/blob/master/LICENSE.txt)
|
50
50
|
|
51
51
|
[](https://github.com/ragardner/tksheet/releases) [](https://pypi.org/project/tksheet/)
|
52
52
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# <div align="center">tksheet - python tkinter table widget</div>
|
6
6
|
|
7
|
-
[](https://pypi.python.org/pypi/tksheet/)  [](https://github.com/ragardner/tksheet/blob/master/LICENSE.txt)
|
7
|
+
[](https://pypi.python.org/pypi/tksheet/)  [](https://github.com/ragardner/tksheet/blob/master/LICENSE.txt)
|
8
8
|
|
9
9
|
[](https://github.com/ragardner/tksheet/releases) [](https://pypi.org/project/tksheet/)
|
10
10
|
|
@@ -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.22"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
3
3
|
import tkinter as tk
|
4
4
|
from collections import defaultdict
|
5
5
|
from collections.abc import (
|
6
|
-
Callable,
|
7
6
|
Hashable,
|
8
7
|
Sequence,
|
9
8
|
)
|
@@ -31,7 +30,7 @@ from .functions import (
|
|
31
30
|
get_n2a,
|
32
31
|
is_contiguous,
|
33
32
|
new_tk_event,
|
34
|
-
|
33
|
+
stored_event_dict,
|
35
34
|
rounded_box_coords,
|
36
35
|
try_binding,
|
37
36
|
)
|
@@ -874,7 +873,7 @@ class ColumnHeaders(tk.Canvas):
|
|
874
873
|
"displayed": disp_new_idxs,
|
875
874
|
}
|
876
875
|
if self.MT.undo_enabled:
|
877
|
-
self.MT.undo_stack.append(
|
876
|
+
self.MT.undo_stack.append(stored_event_dict(event_data))
|
878
877
|
self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
|
879
878
|
try_binding(self.ch_extra_end_drag_drop_func, event_data, "end_move_columns")
|
880
879
|
self.MT.sheet_modified(event_data)
|
@@ -1190,45 +1189,44 @@ class ColumnHeaders(tk.Canvas):
|
|
1190
1189
|
fc: float,
|
1191
1190
|
sc: float,
|
1192
1191
|
c: int,
|
1193
|
-
|
1194
|
-
|
1192
|
+
sel_cells_bg: str,
|
1193
|
+
sel_cols_bg: str,
|
1195
1194
|
selections: dict,
|
1196
1195
|
datacn: int,
|
1197
1196
|
) -> tuple[str, bool]:
|
1198
1197
|
redrawn = False
|
1199
1198
|
kwargs = self.get_cell_kwargs(datacn, key="highlight")
|
1200
1199
|
if kwargs:
|
1201
|
-
|
1202
|
-
|
1200
|
+
fill = kwargs[0]
|
1201
|
+
if fill and not fill.startswith("#"):
|
1202
|
+
fill = color_map[fill]
|
1203
1203
|
if "columns" in selections and c in selections["columns"]:
|
1204
|
-
|
1204
|
+
txtfg = (
|
1205
1205
|
self.PAR.ops.header_selected_columns_fg
|
1206
1206
|
if kwargs[1] is None or self.PAR.ops.display_selected_fg_over_highlights
|
1207
1207
|
else kwargs[1]
|
1208
1208
|
)
|
1209
|
-
if
|
1209
|
+
if fill:
|
1210
1210
|
fill = (
|
1211
|
-
f"#{int((int(
|
1212
|
-
+ f"{int((int(
|
1213
|
-
+ f"{int((int(
|
1211
|
+
f"#{int((int(fill[1:3], 16) + int(sel_cols_bg[1:3], 16)) / 2):02X}"
|
1212
|
+
+ f"{int((int(fill[3:5], 16) + int(sel_cols_bg[3:5], 16)) / 2):02X}"
|
1213
|
+
+ f"{int((int(fill[5:], 16) + int(sel_cols_bg[5:], 16)) / 2):02X}"
|
1214
1214
|
)
|
1215
1215
|
elif "cells" in selections and c in selections["cells"]:
|
1216
|
-
|
1216
|
+
txtfg = (
|
1217
1217
|
self.PAR.ops.header_selected_cells_fg
|
1218
1218
|
if kwargs[1] is None or self.PAR.ops.display_selected_fg_over_highlights
|
1219
1219
|
else kwargs[1]
|
1220
1220
|
)
|
1221
|
-
if
|
1221
|
+
if fill:
|
1222
1222
|
fill = (
|
1223
|
-
f"#{int((int(
|
1224
|
-
+ f"{int((int(
|
1225
|
-
+ f"{int((int(
|
1223
|
+
f"#{int((int(fill[1:3], 16) + int(sel_cells_bg[1:3], 16)) / 2):02X}"
|
1224
|
+
+ f"{int((int(fill[3:5], 16) + int(sel_cells_bg[3:5], 16)) / 2):02X}"
|
1225
|
+
+ f"{int((int(fill[5:], 16) + int(sel_cells_bg[5:], 16)) / 2):02X}"
|
1226
1226
|
)
|
1227
1227
|
else:
|
1228
|
-
|
1229
|
-
|
1230
|
-
fill = kwargs[0]
|
1231
|
-
if kwargs[0] is not None:
|
1228
|
+
txtfg = self.PAR.ops.header_fg if kwargs[1] is None else kwargs[1]
|
1229
|
+
if fill:
|
1232
1230
|
redrawn = self.redraw_highlight(
|
1233
1231
|
fc + 1,
|
1234
1232
|
0,
|
@@ -1244,12 +1242,12 @@ class ColumnHeaders(tk.Canvas):
|
|
1244
1242
|
)
|
1245
1243
|
elif not kwargs:
|
1246
1244
|
if "columns" in selections and c in selections["columns"]:
|
1247
|
-
|
1245
|
+
txtfg = self.PAR.ops.header_selected_columns_fg
|
1248
1246
|
elif "cells" in selections and c in selections["cells"]:
|
1249
|
-
|
1247
|
+
txtfg = self.PAR.ops.header_selected_cells_fg
|
1250
1248
|
else:
|
1251
|
-
|
1252
|
-
return
|
1249
|
+
txtfg = self.PAR.ops.header_fg
|
1250
|
+
return txtfg, redrawn
|
1253
1251
|
|
1254
1252
|
def redraw_highlight(
|
1255
1253
|
self,
|
@@ -1463,12 +1461,12 @@ class ColumnHeaders(tk.Canvas):
|
|
1463
1461
|
)
|
1464
1462
|
self.redraw_gridline(points=points, fill=self.PAR.ops.header_grid_fg, width=1, tag="v")
|
1465
1463
|
top = self.canvasy(0)
|
1466
|
-
|
1464
|
+
sel_cols_bg = (
|
1467
1465
|
self.PAR.ops.header_selected_cells_bg
|
1468
1466
|
if self.PAR.ops.header_selected_cells_bg.startswith("#")
|
1469
1467
|
else color_map[self.PAR.ops.header_selected_cells_bg]
|
1470
1468
|
)
|
1471
|
-
|
1469
|
+
sel_cells_bg = (
|
1472
1470
|
self.PAR.ops.header_selected_columns_bg
|
1473
1471
|
if self.PAR.ops.header_selected_columns_bg.startswith("#")
|
1474
1472
|
else color_map[self.PAR.ops.header_selected_columns_bg]
|
@@ -1482,7 +1480,13 @@ class ColumnHeaders(tk.Canvas):
|
|
1482
1480
|
crightgridln = self.MT.col_positions[c + 1]
|
1483
1481
|
datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
|
1484
1482
|
fill, dd_drawn = self.redraw_highlight_get_text_fg(
|
1485
|
-
cleftgridln,
|
1483
|
+
fc=cleftgridln,
|
1484
|
+
sc=crightgridln,
|
1485
|
+
c=c,
|
1486
|
+
sel_cells_bg=sel_cells_bg,
|
1487
|
+
sel_cols_bg=sel_cols_bg,
|
1488
|
+
selections=selections,
|
1489
|
+
datacn=datacn,
|
1486
1490
|
)
|
1487
1491
|
|
1488
1492
|
if datacn in self.cell_options and "align" in self.cell_options[datacn]:
|
@@ -1500,7 +1504,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1500
1504
|
0,
|
1501
1505
|
crightgridln,
|
1502
1506
|
self.current_height - 1,
|
1503
|
-
fill=fill,
|
1507
|
+
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.header_grid_fg,
|
1504
1508
|
outline=fill,
|
1505
1509
|
tag="dd",
|
1506
1510
|
draw_outline=not dd_drawn,
|
@@ -1519,7 +1523,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1519
1523
|
0,
|
1520
1524
|
crightgridln,
|
1521
1525
|
self.current_height - 1,
|
1522
|
-
fill=fill,
|
1526
|
+
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.header_grid_fg,
|
1523
1527
|
outline=fill,
|
1524
1528
|
tag="dd",
|
1525
1529
|
draw_outline=not dd_drawn,
|
@@ -1539,7 +1543,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1539
1543
|
0,
|
1540
1544
|
crightgridln,
|
1541
1545
|
self.current_height - 1,
|
1542
|
-
fill=fill,
|
1546
|
+
fill=fill if kwargs["state"] != "disabled" else self.PAR.ops.header_grid_fg,
|
1543
1547
|
outline=fill,
|
1544
1548
|
tag="dd",
|
1545
1549
|
draw_outline=not dd_drawn,
|
@@ -1999,20 +2003,42 @@ class ColumnHeaders(tk.Canvas):
|
|
1999
2003
|
|
2000
2004
|
def dropdown_text_editor_modified(
|
2001
2005
|
self,
|
2002
|
-
|
2003
|
-
event: dict,
|
2004
|
-
modified_func: Callable | None,
|
2006
|
+
event: tk.Misc,
|
2005
2007
|
) -> None:
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2008
|
+
c = self.dropdown.get_coords()
|
2009
|
+
event_data = event_dict(
|
2010
|
+
name="table_dropdown_modified",
|
2011
|
+
sheet=self.PAR.name,
|
2012
|
+
value=self.text_editor.get(),
|
2013
|
+
loc=c,
|
2014
|
+
row=0,
|
2015
|
+
column=c,
|
2016
|
+
boxes=self.MT.get_boxes(),
|
2017
|
+
selected=self.MT.selected,
|
2018
|
+
)
|
2019
|
+
try_binding(self.dropdown.window.modified_function, event_data)
|
2020
|
+
val = self.dropdown.window.search_and_see(event_data)
|
2021
|
+
# return to tk.Text action if control/command is held down
|
2022
|
+
# or keysym was not a character
|
2023
|
+
if (hasattr(event, "state") and event.state & (0x0004 | 0x00000010)) or (
|
2024
|
+
hasattr(event, "keysym") and len(event.keysym) > 2
|
2025
|
+
):
|
2026
|
+
return
|
2027
|
+
self.text_editor.tktext.unbind("<KeyRelease>")
|
2028
|
+
self.text_editor.autocomplete(val)
|
2029
|
+
self.text_editor.tktext.bind(
|
2030
|
+
"<KeyRelease>",
|
2031
|
+
self.dropdown_text_editor_modified,
|
2032
|
+
)
|
2033
|
+
return "break"
|
2009
2034
|
|
2010
2035
|
def open_dropdown_window(self, c: int, event: object = None) -> None:
|
2011
2036
|
self.hide_text_editor()
|
2012
2037
|
kwargs = self.get_cell_kwargs(self.MT.datacn(c), key="dropdown")
|
2013
|
-
if kwargs["state"] == "
|
2014
|
-
|
2015
|
-
|
2038
|
+
if kwargs["state"] == "disabled":
|
2039
|
+
return
|
2040
|
+
if kwargs["state"] == "normal" and not self.open_text_editor(event=event, c=c, dropdown=True):
|
2041
|
+
return
|
2016
2042
|
win_h, anchor = self.get_dropdown_height_anchor(c)
|
2017
2043
|
win_w = self.MT.col_positions[c + 1] - self.MT.col_positions[c] + 1
|
2018
2044
|
ypos = self.current_height - 1
|
@@ -2026,6 +2052,8 @@ class ColumnHeaders(tk.Canvas):
|
|
2026
2052
|
"outline_color": self.PAR.ops.header_selected_columns_bg,
|
2027
2053
|
"align": self.get_cell_align(c),
|
2028
2054
|
"values": kwargs["values"],
|
2055
|
+
"search_function": kwargs["search_function"],
|
2056
|
+
"modified_function": kwargs["modified_function"],
|
2029
2057
|
}
|
2030
2058
|
if self.dropdown.window:
|
2031
2059
|
self.dropdown.window.reset(**reset_kwargs)
|
@@ -2038,7 +2066,6 @@ class ColumnHeaders(tk.Canvas):
|
|
2038
2066
|
**reset_kwargs,
|
2039
2067
|
single_index="c",
|
2040
2068
|
close_dropdown_window=self.close_dropdown_window,
|
2041
|
-
search_function=kwargs["search_function"],
|
2042
2069
|
arrowkey_RIGHT=self.MT.arrowkey_RIGHT,
|
2043
2070
|
arrowkey_LEFT=self.MT.arrowkey_LEFT,
|
2044
2071
|
)
|
@@ -2049,20 +2076,8 @@ class ColumnHeaders(tk.Canvas):
|
|
2049
2076
|
)
|
2050
2077
|
if kwargs["state"] == "normal":
|
2051
2078
|
self.text_editor.tktext.bind(
|
2052
|
-
"
|
2053
|
-
|
2054
|
-
self.dropdown.window,
|
2055
|
-
event_dict(
|
2056
|
-
name="header_dropdown_modified",
|
2057
|
-
sheet=self.PAR.name,
|
2058
|
-
value=self.text_editor.get(),
|
2059
|
-
loc=c,
|
2060
|
-
column=c,
|
2061
|
-
boxes=self.MT.get_boxes(),
|
2062
|
-
selected=self.MT.selected,
|
2063
|
-
),
|
2064
|
-
kwargs["modified_function"],
|
2065
|
-
),
|
2079
|
+
"<KeyRelease>",
|
2080
|
+
self.dropdown_text_editor_modified,
|
2066
2081
|
)
|
2067
2082
|
self.update_idletasks()
|
2068
2083
|
try:
|
@@ -2186,7 +2201,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2186
2201
|
self.fix_header(datacn)
|
2187
2202
|
if not check_input_valid or self.input_valid_for_cell(datacn, value):
|
2188
2203
|
if self.MT.undo_enabled and undo:
|
2189
|
-
self.MT.undo_stack.append(
|
2204
|
+
self.MT.undo_stack.append(stored_event_dict(event_data))
|
2190
2205
|
self.set_cell_data(datacn=datacn, value=value)
|
2191
2206
|
edited = True
|
2192
2207
|
if edited and cell_resize and self.PAR.ops.cell_auto_resize_enabled:
|
@@ -5,7 +5,6 @@ import io
|
|
5
5
|
import pickle
|
6
6
|
import re
|
7
7
|
import tkinter as tk
|
8
|
-
import zlib
|
9
8
|
from bisect import (
|
10
9
|
bisect_left,
|
11
10
|
)
|
@@ -16,10 +15,10 @@ from collections.abc import (
|
|
16
15
|
Iterator,
|
17
16
|
Sequence,
|
18
17
|
)
|
19
|
-
from functools import partial
|
20
18
|
from itertools import islice, repeat
|
21
19
|
from typing import Literal
|
22
20
|
|
21
|
+
from .colors import color_map
|
23
22
|
from .formatters import (
|
24
23
|
to_bool,
|
25
24
|
)
|
@@ -32,8 +31,6 @@ from .other_classes import (
|
|
32
31
|
Span,
|
33
32
|
)
|
34
33
|
|
35
|
-
compress = partial(zlib.compress, level=1)
|
36
|
-
pickle_obj = partial(pickle.dumps, protocol=pickle.HIGHEST_PROTOCOL)
|
37
34
|
unpickle_obj = pickle.loads
|
38
35
|
|
39
36
|
|
@@ -65,14 +62,6 @@ def get_data_from_clipboard(
|
|
65
62
|
return [[data]]
|
66
63
|
|
67
64
|
|
68
|
-
def pickle_compress(obj: object) -> bytes:
|
69
|
-
return compress(pickle_obj(obj))
|
70
|
-
|
71
|
-
|
72
|
-
def decompress_load(b: bytes) -> object:
|
73
|
-
return pickle.loads(zlib.decompress(b))
|
74
|
-
|
75
|
-
|
76
65
|
def tksheet_type_error(kwarg: str, valid_types: list[str], not_type: object) -> str:
|
77
66
|
valid_types = ", ".join(f"{type_}" for type_ in valid_types)
|
78
67
|
return f"Argument '{kwarg}' must be one of the following types: {valid_types}, " f"not {type(not_type)}."
|
@@ -210,8 +199,8 @@ def change_eventname(event_dict: EventDataDict, newname: str) -> EventDataDict:
|
|
210
199
|
return EventDataDict({**event_dict, **{"eventname": newname}})
|
211
200
|
|
212
201
|
|
213
|
-
def
|
214
|
-
return DotDict(name=d["eventname"], data=
|
202
|
+
def stored_event_dict(d: DotDict) -> DotDict:
|
203
|
+
return DotDict(name=d["eventname"], data=DotDict(kv for kv in d.items() if kv[0] != "widget"))
|
215
204
|
|
216
205
|
|
217
206
|
def len_to_idx(n: int) -> int:
|
@@ -438,6 +427,20 @@ def is_contiguous(iterable: Iterator[int]) -> bool:
|
|
438
427
|
return all(i == (prev := prev + 1) for i in itr)
|
439
428
|
|
440
429
|
|
430
|
+
def box_is_single_cell(
|
431
|
+
r1: int,
|
432
|
+
c1: int,
|
433
|
+
r2: int,
|
434
|
+
c2: int,
|
435
|
+
) -> bool:
|
436
|
+
return r2 - r1 == 1 and c2 - c1 == 1
|
437
|
+
|
438
|
+
|
439
|
+
def color_tup(color: str) -> tuple[int, int, int]:
|
440
|
+
res = color if color.startswith("#") else color_map[color]
|
441
|
+
return int(res[1:3], 16), int(res[3:5], 16), int(res[5:], 16)
|
442
|
+
|
443
|
+
|
441
444
|
def down_cell_within_box(
|
442
445
|
r: int,
|
443
446
|
c: int,
|