tksheet 7.1.6__tar.gz → 7.1.7__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.1.6/tksheet.egg-info → tksheet-7.1.7}/PKG-INFO +1 -1
- {tksheet-7.1.6 → tksheet-7.1.7}/pyproject.toml +35 -35
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/__init__.py +99 -96
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/column_headers.py +37 -24
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/functions.py +5 -5
- tksheet-7.1.7/tksheet/listbox.py +19 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/main_table.py +299 -266
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/row_index.py +46 -26
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/sheet.py +56 -83
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/sheet_options.py +3 -1
- {tksheet-7.1.6 → tksheet-7.1.7/tksheet.egg-info}/PKG-INFO +1 -1
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet.egg-info/SOURCES.txt +1 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/LICENSE.txt +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/README.md +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/setup.cfg +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/colors.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/formatters.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/other_classes.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/text_editor.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/themes.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/top_left_rectangle.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/types.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet/vars.py +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.1.6 → tksheet-7.1.7}/tksheet.egg-info/top_level.txt +0 -0
@@ -1,35 +1,35 @@
|
|
1
|
-
[build-system]
|
2
|
-
requires = ["setuptools"]
|
3
|
-
build-backend = "setuptools.build_meta"
|
4
|
-
|
5
|
-
[project]
|
6
|
-
name = "tksheet"
|
7
|
-
description = "Tkinter table / sheet widget"
|
8
|
-
readme = "README.md"
|
9
|
-
version = "7.1.
|
10
|
-
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
|
-
requires-python = ">=3.8"
|
12
|
-
license = {file = "LICENSE.txt"}
|
13
|
-
keywords = ["tkinter", "table", "widget", "sheet", "grid", "tk"]
|
14
|
-
classifiers = [
|
15
|
-
"Development Status :: 5 - Production/Stable",
|
16
|
-
"Intended Audience :: Developers",
|
17
|
-
"Topic :: Software Development :: Libraries",
|
18
|
-
"License :: OSI Approved :: MIT License",
|
19
|
-
"Programming Language :: Python :: 3.8",
|
20
|
-
"Programming Language :: Python :: 3.9",
|
21
|
-
"Programming Language :: Python :: 3.10",
|
22
|
-
"Programming Language :: Python :: 3.11",
|
23
|
-
"Programming Language :: Python :: 3.12",
|
24
|
-
]
|
25
|
-
|
26
|
-
[project.urls]
|
27
|
-
"Homepage" = "https://github.com/ragardner/tksheet"
|
28
|
-
"Bug Reports" = "https://github.com/ragardner/tksheet/issues"
|
29
|
-
"Funding" = "https://github.com/ragardner"
|
30
|
-
|
31
|
-
[tool.black]
|
32
|
-
line-length = 120
|
33
|
-
|
34
|
-
[tool.ruff]
|
35
|
-
line-length = 120
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "tksheet"
|
7
|
+
description = "Tkinter table / sheet widget"
|
8
|
+
readme = "README.md"
|
9
|
+
version = "7.1.7"
|
10
|
+
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
|
+
requires-python = ">=3.8"
|
12
|
+
license = {file = "LICENSE.txt"}
|
13
|
+
keywords = ["tkinter", "table", "widget", "sheet", "grid", "tk"]
|
14
|
+
classifiers = [
|
15
|
+
"Development Status :: 5 - Production/Stable",
|
16
|
+
"Intended Audience :: Developers",
|
17
|
+
"Topic :: Software Development :: Libraries",
|
18
|
+
"License :: OSI Approved :: MIT License",
|
19
|
+
"Programming Language :: Python :: 3.8",
|
20
|
+
"Programming Language :: Python :: 3.9",
|
21
|
+
"Programming Language :: Python :: 3.10",
|
22
|
+
"Programming Language :: Python :: 3.11",
|
23
|
+
"Programming Language :: Python :: 3.12",
|
24
|
+
]
|
25
|
+
|
26
|
+
[project.urls]
|
27
|
+
"Homepage" = "https://github.com/ragardner/tksheet"
|
28
|
+
"Bug Reports" = "https://github.com/ragardner/tksheet/issues"
|
29
|
+
"Funding" = "https://github.com/ragardner"
|
30
|
+
|
31
|
+
[tool.black]
|
32
|
+
line-length = 120
|
33
|
+
|
34
|
+
[tool.ruff]
|
35
|
+
line-length = 120
|
@@ -1,96 +1,99 @@
|
|
1
|
-
# ruff: noqa: F401
|
2
|
-
|
3
|
-
"""
|
4
|
-
tksheet - A Python tkinter table widget
|
5
|
-
"""
|
6
|
-
|
7
|
-
__version__ = "7.1.
|
8
|
-
|
9
|
-
from .colors import (
|
10
|
-
color_map,
|
11
|
-
)
|
12
|
-
from .column_headers import ColumnHeaders
|
13
|
-
from .formatters import (
|
14
|
-
Formatter,
|
15
|
-
bool_formatter,
|
16
|
-
data_to_str,
|
17
|
-
float_formatter,
|
18
|
-
float_to_str,
|
19
|
-
format_data,
|
20
|
-
formatter,
|
21
|
-
get_clipboard_data,
|
22
|
-
get_data_with_valid_check,
|
23
|
-
int_formatter,
|
24
|
-
is_bool_like,
|
25
|
-
is_none_like,
|
26
|
-
percentage_formatter,
|
27
|
-
percentage_to_str,
|
28
|
-
to_bool,
|
29
|
-
to_float,
|
30
|
-
to_int,
|
31
|
-
to_str,
|
32
|
-
try_to_bool,
|
33
|
-
)
|
34
|
-
from .functions import (
|
35
|
-
alpha2idx,
|
36
|
-
alpha2num,
|
37
|
-
consecutive_chunks,
|
38
|
-
data_to_displayed_idxs,
|
39
|
-
displayed_to_data_idxs,
|
40
|
-
dropdown_search_function,
|
41
|
-
event_dict,
|
42
|
-
get_checkbox_dict,
|
43
|
-
get_checkbox_kwargs,
|
44
|
-
|
45
|
-
get_dropdown_dict,
|
46
|
-
get_dropdown_kwargs,
|
47
|
-
get_index_of_gap_in_sorted_integer_seq_forward,
|
48
|
-
get_index_of_gap_in_sorted_integer_seq_reverse,
|
49
|
-
get_n2a,
|
50
|
-
get_new_indexes,
|
51
|
-
get_seq_without_gaps_at_index,
|
52
|
-
is_iterable,
|
53
|
-
move_elements_by_mapping,
|
54
|
-
move_elements_to,
|
55
|
-
num2alpha,
|
56
|
-
span_dict,
|
57
|
-
tksheet_type_error,
|
58
|
-
)
|
59
|
-
from .
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
from .
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
1
|
+
# ruff: noqa: F401
|
2
|
+
|
3
|
+
"""
|
4
|
+
tksheet - A Python tkinter table widget
|
5
|
+
"""
|
6
|
+
|
7
|
+
__version__ = "7.1.7"
|
8
|
+
|
9
|
+
from .colors import (
|
10
|
+
color_map,
|
11
|
+
)
|
12
|
+
from .column_headers import ColumnHeaders
|
13
|
+
from .formatters import (
|
14
|
+
Formatter,
|
15
|
+
bool_formatter,
|
16
|
+
data_to_str,
|
17
|
+
float_formatter,
|
18
|
+
float_to_str,
|
19
|
+
format_data,
|
20
|
+
formatter,
|
21
|
+
get_clipboard_data,
|
22
|
+
get_data_with_valid_check,
|
23
|
+
int_formatter,
|
24
|
+
is_bool_like,
|
25
|
+
is_none_like,
|
26
|
+
percentage_formatter,
|
27
|
+
percentage_to_str,
|
28
|
+
to_bool,
|
29
|
+
to_float,
|
30
|
+
to_int,
|
31
|
+
to_str,
|
32
|
+
try_to_bool,
|
33
|
+
)
|
34
|
+
from .functions import (
|
35
|
+
alpha2idx,
|
36
|
+
alpha2num,
|
37
|
+
consecutive_chunks,
|
38
|
+
data_to_displayed_idxs,
|
39
|
+
displayed_to_data_idxs,
|
40
|
+
dropdown_search_function,
|
41
|
+
event_dict,
|
42
|
+
get_checkbox_dict,
|
43
|
+
get_checkbox_kwargs,
|
44
|
+
rounded_box_coords,
|
45
|
+
get_dropdown_dict,
|
46
|
+
get_dropdown_kwargs,
|
47
|
+
get_index_of_gap_in_sorted_integer_seq_forward,
|
48
|
+
get_index_of_gap_in_sorted_integer_seq_reverse,
|
49
|
+
get_n2a,
|
50
|
+
get_new_indexes,
|
51
|
+
get_seq_without_gaps_at_index,
|
52
|
+
is_iterable,
|
53
|
+
move_elements_by_mapping,
|
54
|
+
move_elements_to,
|
55
|
+
num2alpha,
|
56
|
+
span_dict,
|
57
|
+
tksheet_type_error,
|
58
|
+
)
|
59
|
+
from .listbox import (
|
60
|
+
ListBox,
|
61
|
+
)
|
62
|
+
from .main_table import MainTable
|
63
|
+
from .other_classes import (
|
64
|
+
DotDict,
|
65
|
+
DraggedRowColumn,
|
66
|
+
DrawnItem,
|
67
|
+
EventDataDict,
|
68
|
+
GeneratedMouseEvent,
|
69
|
+
Selected,
|
70
|
+
Span,
|
71
|
+
SpanRange,
|
72
|
+
TextCfg,
|
73
|
+
)
|
74
|
+
from .row_index import RowIndex
|
75
|
+
from .sheet import Dropdown, Sheet
|
76
|
+
from .sheet_options import new_sheet_options
|
77
|
+
from .text_editor import (
|
78
|
+
TextEditor,
|
79
|
+
TextEditorTkText,
|
80
|
+
)
|
81
|
+
from .themes import (
|
82
|
+
theme_black,
|
83
|
+
theme_dark,
|
84
|
+
theme_dark_blue,
|
85
|
+
theme_dark_green,
|
86
|
+
theme_light_blue,
|
87
|
+
theme_light_green,
|
88
|
+
)
|
89
|
+
from .top_left_rectangle import TopLeftRectangle
|
90
|
+
from .vars import (
|
91
|
+
USER_OS,
|
92
|
+
ctrl_key,
|
93
|
+
emitted_events,
|
94
|
+
falsy,
|
95
|
+
nonelike,
|
96
|
+
rc_binding,
|
97
|
+
symbols_set,
|
98
|
+
truthy,
|
99
|
+
)
|
@@ -23,7 +23,7 @@ from .functions import (
|
|
23
23
|
consecutive_ranges,
|
24
24
|
ev_stack_dict,
|
25
25
|
event_dict,
|
26
|
-
|
26
|
+
rounded_box_coords,
|
27
27
|
get_n2a,
|
28
28
|
is_contiguous,
|
29
29
|
try_binding,
|
@@ -935,14 +935,26 @@ class ColumnHeaders(tk.Canvas):
|
|
935
935
|
outline: str,
|
936
936
|
state: str,
|
937
937
|
tags: str | tuple[str],
|
938
|
+
iid: None | int = None,
|
938
939
|
) -> int:
|
939
|
-
|
940
|
-
|
941
|
-
|
940
|
+
coords = rounded_box_coords(
|
941
|
+
x1,
|
942
|
+
y1,
|
943
|
+
x2,
|
944
|
+
y2,
|
945
|
+
radius=9 if self.PAR.ops.rounded_boxes else 0,
|
946
|
+
)
|
947
|
+
if isinstance(iid, int):
|
948
|
+
self.coords(iid, coords)
|
942
949
|
self.itemconfig(iid, fill=fill, outline=outline, state=state, tags=tags)
|
943
950
|
else:
|
944
|
-
|
945
|
-
|
951
|
+
if self.hidd_boxes:
|
952
|
+
iid = self.hidd_boxes.pop()
|
953
|
+
self.coords(iid, coords)
|
954
|
+
self.itemconfig(iid, fill=fill, outline=outline, state=state, tags=tags)
|
955
|
+
else:
|
956
|
+
iid = self.create_polygon(coords, fill=fill, outline=outline, state=state, tags=tags, smooth=True)
|
957
|
+
self.disp_boxes.add(iid)
|
946
958
|
return iid
|
947
959
|
|
948
960
|
def hide_box(self, item: int) -> None:
|
@@ -1276,7 +1288,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1276
1288
|
self.disp_dropdown[t] = True
|
1277
1289
|
|
1278
1290
|
def redraw_checkbox(self, x1, y1, x2, y2, fill, outline, tag, draw_check=False):
|
1279
|
-
points =
|
1291
|
+
points = rounded_box_coords(x1, y1, x2, y2)
|
1280
1292
|
if self.hidd_checkbox:
|
1281
1293
|
t, sh = self.hidd_checkbox.popitem()
|
1282
1294
|
self.coords(t, points)
|
@@ -1294,7 +1306,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1294
1306
|
y1 = y1 + 4
|
1295
1307
|
x2 = x2 - 3
|
1296
1308
|
y2 = y2 - 3
|
1297
|
-
points =
|
1309
|
+
points = rounded_box_coords(x1, y1, x2, y2, radius=4)
|
1298
1310
|
if self.hidd_checkbox:
|
1299
1311
|
t, sh = self.hidd_checkbox.popitem()
|
1300
1312
|
self.coords(t, points)
|
@@ -1574,16 +1586,14 @@ class ColumnHeaders(tk.Canvas):
|
|
1574
1586
|
dct[iid] = False
|
1575
1587
|
return True
|
1576
1588
|
|
1577
|
-
def get_redraw_selections(self, startc, endc):
|
1578
|
-
d = defaultdict(
|
1589
|
+
def get_redraw_selections(self, startc: int, endc: int) -> dict[str, set[int]]:
|
1590
|
+
d = defaultdict(set)
|
1579
1591
|
for item, box in self.MT.get_selection_items(rows=False):
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
d2["columns"] = {c for c in range(startc, endc) for r1, c1, r2, c2 in d["columns"] if c1 <= c and c2 > c}
|
1586
|
-
return d2
|
1592
|
+
r1, c1, r2, c2 = box.coords
|
1593
|
+
for c in range(startc, endc):
|
1594
|
+
if c1 <= c and c2 > c:
|
1595
|
+
d[box.type_].add(c)
|
1596
|
+
return d
|
1587
1597
|
|
1588
1598
|
def open_cell(self, event: object = None, ignore_existing_editor=False):
|
1589
1599
|
if not self.MT.anything_selected() or (not ignore_existing_editor and self.text_editor.open):
|
@@ -1817,6 +1827,8 @@ class ColumnHeaders(tk.Canvas):
|
|
1817
1827
|
|
1818
1828
|
def hide_text_editor(self, reason: None | str = None) -> None:
|
1819
1829
|
if self.text_editor.open:
|
1830
|
+
for b in ("<Alt-Return>", "<Option-Return>", "<Tab>", "<Return>", "<FocusOut>", "<Escape>"):
|
1831
|
+
self.text_editor.tktext.unbind(b)
|
1820
1832
|
self.itemconfig(self.text_editor.canvas_id, state="hidden")
|
1821
1833
|
self.text_editor.open = False
|
1822
1834
|
if reason == "Escape":
|
@@ -1840,7 +1852,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1840
1852
|
self.hide_text_editor_and_dropdown()
|
1841
1853
|
return
|
1842
1854
|
# setting cell data with text editor value
|
1843
|
-
|
1855
|
+
text_editor_value = self.text_editor.get()
|
1844
1856
|
c = editor_info[0]
|
1845
1857
|
datacn = c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
|
1846
1858
|
event_data = event_dict(
|
@@ -1848,7 +1860,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1848
1860
|
sheet=self.PAR.name,
|
1849
1861
|
cells_header={datacn: self.get_cell_data(datacn)},
|
1850
1862
|
key=editor_info[1] if len(editor_info) >= 2 else "FocusOut",
|
1851
|
-
value=
|
1863
|
+
value=text_editor_value,
|
1852
1864
|
loc=c,
|
1853
1865
|
boxes=self.MT.get_boxes(),
|
1854
1866
|
selected=self.MT.selected,
|
@@ -1861,11 +1873,11 @@ class ColumnHeaders(tk.Canvas):
|
|
1861
1873
|
check_input_valid=False,
|
1862
1874
|
)
|
1863
1875
|
if self.MT.edit_validation_func:
|
1864
|
-
|
1865
|
-
if
|
1866
|
-
edited = set_data(value=
|
1867
|
-
elif self.input_valid_for_cell(datacn,
|
1868
|
-
edited = set_data(value=
|
1876
|
+
text_editor_value = self.MT.edit_validation_func(event_data)
|
1877
|
+
if text_editor_value is not None and self.input_valid_for_cell(datacn, text_editor_value):
|
1878
|
+
edited = set_data(value=text_editor_value)
|
1879
|
+
elif self.input_valid_for_cell(datacn, text_editor_value):
|
1880
|
+
edited = set_data(value=text_editor_value)
|
1869
1881
|
if edited:
|
1870
1882
|
try_binding(self.extra_end_edit_cell_func, event_data)
|
1871
1883
|
self.MT.recreate_all_selection_boxes()
|
@@ -2037,6 +2049,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2037
2049
|
|
2038
2050
|
def hide_dropdown_window(self) -> None:
|
2039
2051
|
if self.dropdown.open:
|
2052
|
+
self.dropdown.window.unbind("<FocusOut>")
|
2040
2053
|
self.itemconfig(self.dropdown.canvas_id, state="hidden")
|
2041
2054
|
self.dropdown.open = False
|
2042
2055
|
|
@@ -356,7 +356,7 @@ def consecutive_chunks(seq: list[int]) -> Generator[list[int]]:
|
|
356
356
|
for index, value in enumerate(seq, 1):
|
357
357
|
try:
|
358
358
|
if seq[index] > value + 1:
|
359
|
-
yield seq[start:(start := index)]
|
359
|
+
yield seq[start : (start := index)]
|
360
360
|
except Exception:
|
361
361
|
yield seq[start : len(seq)]
|
362
362
|
|
@@ -504,14 +504,14 @@ def displayed_to_data_idxs(
|
|
504
504
|
return [displayed[e] for e in to_convert]
|
505
505
|
|
506
506
|
|
507
|
-
def
|
507
|
+
def rounded_box_coords(
|
508
508
|
x1: float,
|
509
509
|
y1: float,
|
510
510
|
x2: float,
|
511
511
|
y2: float,
|
512
512
|
radius: int = 8,
|
513
|
-
) ->
|
514
|
-
return
|
513
|
+
) -> tuple[float]:
|
514
|
+
return (
|
515
515
|
x1 + radius,
|
516
516
|
y1,
|
517
517
|
x1 + radius,
|
@@ -552,7 +552,7 @@ def get_checkbox_points(
|
|
552
552
|
y1 + radius,
|
553
553
|
x1,
|
554
554
|
y1,
|
555
|
-
|
555
|
+
)
|
556
556
|
|
557
557
|
|
558
558
|
def diff_list(seq: list[float]) -> list[int]:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import tkinter as tk
|
3
|
+
# from collections.abc import Callable, Generator, Iterator, Sequence
|
4
|
+
|
5
|
+
from .sheet import (
|
6
|
+
Sheet,
|
7
|
+
)
|
8
|
+
|
9
|
+
|
10
|
+
class ListBox(Sheet):
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
parent: tk.Misc,
|
14
|
+
) -> None:
|
15
|
+
Sheet.__init__(
|
16
|
+
self,
|
17
|
+
parent=parent,
|
18
|
+
)
|
19
|
+
self.parent = parent
|