tksheet 7.4.13__tar.gz → 7.4.15__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.4.13/tksheet.egg-info → tksheet-7.4.15}/PKG-INFO +3 -2
- {tksheet-7.4.13 → tksheet-7.4.15}/pyproject.toml +2 -1
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/__init__.py +1 -1
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/column_headers.py +91 -76
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/find_window.py +2 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/main_table.py +482 -464
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/row_index.py +91 -85
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/sheet.py +8 -6
- {tksheet-7.4.13 → tksheet-7.4.15/tksheet.egg-info}/PKG-INFO +3 -2
- {tksheet-7.4.13 → tksheet-7.4.15}/LICENSE.txt +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/README.md +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/setup.cfg +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/colors.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/constants.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/formatters.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/functions.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/other_classes.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/sheet_options.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/sorting.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/text_editor.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/themes.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/tksheet_types.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet/top_left_rectangle.py +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.4.13 → tksheet-7.4.15}/tksheet.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: tksheet
|
3
|
-
Version: 7.4.
|
3
|
+
Version: 7.4.15
|
4
4
|
Summary: Tkinter table / sheet and treeview widget
|
5
5
|
Author-email: ragardner <github@ragardner.simplelogin.com>
|
6
6
|
License: Copyright (c) 2019 ragardner and open source contributors
|
@@ -42,6 +42,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
42
42
|
Requires-Python: >=3.8
|
43
43
|
Description-Content-Type: text/markdown
|
44
44
|
License-File: LICENSE.txt
|
45
|
+
Dynamic: license-file
|
45
46
|
|
46
47
|
<p align="center" width="100%">
|
47
48
|
<img width="45%" src="https://github.com/user-attachments/assets/4afc1783-6461-4b98-93cb-b2a2a7f35169" alt="tksheet table">
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
6
6
|
name = "tksheet"
|
7
7
|
description = "Tkinter table / sheet and treeview widget"
|
8
8
|
readme = "README.md"
|
9
|
-
version = "7.4.
|
9
|
+
version = "7.4.15"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -35,3 +35,4 @@ Funding = "https://github.com/ragardner"
|
|
35
35
|
line-length = 120
|
36
36
|
extend-select = ["I", "F", "C4", "E", "B", "SIM"]
|
37
37
|
fix = true
|
38
|
+
ignore = ["SIM401"]
|
@@ -1283,7 +1283,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1283
1283
|
self.current_height - 1,
|
1284
1284
|
fill=fill,
|
1285
1285
|
outline=self.ops.header_fg if has_dd and self.ops.show_dropdown_borders else "",
|
1286
|
-
tag="hi",
|
1287
1286
|
)
|
1288
1287
|
elif not kwargs:
|
1289
1288
|
if "columns" in selections and c in selections["columns"]:
|
@@ -1295,7 +1294,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1295
1294
|
self.current_height - 1,
|
1296
1295
|
fill=self.ops.header_selected_columns_bg,
|
1297
1296
|
outline=self.ops.header_fg if has_dd and self.ops.show_dropdown_borders else "",
|
1298
|
-
tag="hi",
|
1299
1297
|
)
|
1300
1298
|
elif "cells" in selections and c in selections["cells"]:
|
1301
1299
|
txtfg = self.ops.header_selected_cells_fg
|
@@ -1306,7 +1304,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1306
1304
|
self.current_height - 1,
|
1307
1305
|
fill=self.ops.header_selected_cells_bg,
|
1308
1306
|
outline=self.ops.header_fg if has_dd and self.ops.show_dropdown_borders else "",
|
1309
|
-
tag="hi",
|
1310
1307
|
)
|
1311
1308
|
else:
|
1312
1309
|
txtfg = self.ops.header_fg
|
@@ -1320,7 +1317,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1320
1317
|
y2: float,
|
1321
1318
|
fill: str,
|
1322
1319
|
outline: str,
|
1323
|
-
tag: str | tuple[str],
|
1324
1320
|
) -> bool:
|
1325
1321
|
coords = (x1, y1, x2, y2)
|
1326
1322
|
if self.hidd_high:
|
@@ -1329,10 +1325,9 @@ class ColumnHeaders(tk.Canvas):
|
|
1329
1325
|
if showing:
|
1330
1326
|
self.itemconfig(iid, fill=fill, outline=outline)
|
1331
1327
|
else:
|
1332
|
-
self.itemconfig(iid, fill=fill, outline=outline,
|
1333
|
-
self.tag_raise(iid)
|
1328
|
+
self.itemconfig(iid, fill=fill, outline=outline, state="normal")
|
1334
1329
|
else:
|
1335
|
-
iid = self.create_rectangle(coords, fill=fill, outline=outline
|
1330
|
+
iid = self.create_rectangle(coords, fill=fill, outline=outline)
|
1336
1331
|
self.disp_high[iid] = True
|
1337
1332
|
return True
|
1338
1333
|
|
@@ -1341,19 +1336,17 @@ class ColumnHeaders(tk.Canvas):
|
|
1341
1336
|
points: Sequence[float],
|
1342
1337
|
fill: str,
|
1343
1338
|
width: int,
|
1344
|
-
tag: str | tuple[str],
|
1345
1339
|
) -> None:
|
1346
1340
|
if self.hidd_grid:
|
1347
1341
|
t, sh = self.hidd_grid.popitem()
|
1348
1342
|
self.coords(t, points)
|
1349
1343
|
if sh:
|
1350
|
-
self.itemconfig(t, fill=fill, width=width
|
1344
|
+
self.itemconfig(t, fill=fill, width=width)
|
1351
1345
|
else:
|
1352
|
-
self.itemconfig(t, fill=fill, width=width,
|
1346
|
+
self.itemconfig(t, fill=fill, width=width, state="normal")
|
1353
1347
|
self.disp_grid[t] = True
|
1354
|
-
self.tag_raise(t)
|
1355
1348
|
else:
|
1356
|
-
self.disp_grid[self.create_line(points, fill=fill, width=width
|
1349
|
+
self.disp_grid[self.create_line(points, fill=fill, width=width)] = True
|
1357
1350
|
|
1358
1351
|
def redraw_dropdown(
|
1359
1352
|
self,
|
@@ -1363,13 +1356,12 @@ class ColumnHeaders(tk.Canvas):
|
|
1363
1356
|
y2: float,
|
1364
1357
|
fill: str,
|
1365
1358
|
outline: str,
|
1366
|
-
tag: str | tuple[str],
|
1367
1359
|
draw_outline: bool = True,
|
1368
1360
|
draw_arrow: bool = True,
|
1369
1361
|
open_: bool = False,
|
1370
1362
|
) -> None:
|
1371
1363
|
if draw_outline and self.ops.show_dropdown_borders:
|
1372
|
-
self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.ops.header_fg
|
1364
|
+
self.redraw_highlight(x1 + 1, y1 + 1, x2, y2, fill="", outline=self.ops.header_fg)
|
1373
1365
|
if draw_arrow:
|
1374
1366
|
mod = (self.MT.header_txt_height - 1) if self.MT.header_txt_height % 2 else self.MT.header_txt_height
|
1375
1367
|
small_mod = int(mod / 5)
|
@@ -1400,17 +1392,9 @@ class ColumnHeaders(tk.Canvas):
|
|
1400
1392
|
if sh:
|
1401
1393
|
self.itemconfig(t, fill=fill)
|
1402
1394
|
else:
|
1403
|
-
self.itemconfig(t, fill=fill,
|
1404
|
-
self.lift(t)
|
1395
|
+
self.itemconfig(t, fill=fill, state="normal")
|
1405
1396
|
else:
|
1406
|
-
t = self.create_line(
|
1407
|
-
points,
|
1408
|
-
fill=fill,
|
1409
|
-
tag=tag,
|
1410
|
-
width=2,
|
1411
|
-
capstyle=tk.ROUND,
|
1412
|
-
joinstyle=tk.BEVEL,
|
1413
|
-
)
|
1397
|
+
t = self.create_line(points, fill=fill, width=2, capstyle=tk.ROUND, joinstyle=tk.BEVEL, tag="lift")
|
1414
1398
|
self.disp_dropdown[t] = True
|
1415
1399
|
|
1416
1400
|
def redraw_checkbox(
|
@@ -1421,7 +1405,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1421
1405
|
y2: float,
|
1422
1406
|
fill: str,
|
1423
1407
|
outline: str,
|
1424
|
-
tag: str | tuple[str],
|
1425
1408
|
draw_check: bool = False,
|
1426
1409
|
) -> None:
|
1427
1410
|
points = rounded_box_coords(x1, y1, x2, y2)
|
@@ -1431,10 +1414,9 @@ class ColumnHeaders(tk.Canvas):
|
|
1431
1414
|
if sh:
|
1432
1415
|
self.itemconfig(t, fill=outline, outline=fill)
|
1433
1416
|
else:
|
1434
|
-
self.itemconfig(t, fill=outline, outline=fill,
|
1435
|
-
self.lift(t)
|
1417
|
+
self.itemconfig(t, fill=outline, outline=fill, state="normal")
|
1436
1418
|
else:
|
1437
|
-
t = self.create_polygon(points, fill=outline, outline=fill,
|
1419
|
+
t = self.create_polygon(points, fill=outline, outline=fill, smooth=True, tag="lift")
|
1438
1420
|
self.disp_checkbox[t] = True
|
1439
1421
|
if draw_check:
|
1440
1422
|
# draw filled box
|
@@ -1449,10 +1431,9 @@ class ColumnHeaders(tk.Canvas):
|
|
1449
1431
|
if sh:
|
1450
1432
|
self.itemconfig(t, fill=fill, outline=outline)
|
1451
1433
|
else:
|
1452
|
-
self.itemconfig(t, fill=fill, outline=outline,
|
1453
|
-
self.lift(t)
|
1434
|
+
self.itemconfig(t, fill=fill, outline=outline, state="normal")
|
1454
1435
|
else:
|
1455
|
-
t = self.create_polygon(points, fill=fill, outline=outline,
|
1436
|
+
t = self.create_polygon(points, fill=fill, outline=outline, smooth=True, tag="lift")
|
1456
1437
|
self.disp_checkbox[t] = True
|
1457
1438
|
|
1458
1439
|
def configure_scrollregion(self, last_col_line_pos: float) -> bool:
|
@@ -1470,15 +1451,15 @@ class ColumnHeaders(tk.Canvas):
|
|
1470
1451
|
return False
|
1471
1452
|
|
1472
1453
|
def wrap_get_char_w(self, c: str) -> int:
|
1473
|
-
self.MT.txt_measure_canvas.itemconfig(
|
1474
|
-
self.MT.txt_measure_canvas_text,
|
1475
|
-
text=_test_str + c,
|
1476
|
-
font=self.header_font,
|
1477
|
-
)
|
1478
|
-
b = self.MT.txt_measure_canvas.bbox(self.MT.txt_measure_canvas_text)
|
1479
1454
|
if c in self.MT.char_widths[self.header_font]:
|
1480
1455
|
return self.MT.char_widths[self.header_font][c]
|
1481
1456
|
else:
|
1457
|
+
self.MT.txt_measure_canvas.itemconfig(
|
1458
|
+
self.MT.txt_measure_canvas_text,
|
1459
|
+
text=_test_str + c,
|
1460
|
+
font=self.header_font,
|
1461
|
+
)
|
1462
|
+
b = self.MT.txt_measure_canvas.bbox(self.MT.txt_measure_canvas_text)
|
1482
1463
|
wd = b[2] - b[0] - self.header_test_str_w
|
1483
1464
|
self.MT.char_widths[self.header_font][c] = wd
|
1484
1465
|
return wd
|
@@ -1516,6 +1497,35 @@ class ColumnHeaders(tk.Canvas):
|
|
1516
1497
|
self.current_height,
|
1517
1498
|
)
|
1518
1499
|
top = self.canvasy(0)
|
1500
|
+
|
1501
|
+
if (self.ops.show_vertical_grid or self.width_resizing_enabled) and col_pos_exists:
|
1502
|
+
yend = self.current_height - 5
|
1503
|
+
points = [
|
1504
|
+
x_stop - 1,
|
1505
|
+
self.current_height - 1,
|
1506
|
+
scrollpos_left - 1,
|
1507
|
+
self.current_height - 1,
|
1508
|
+
scrollpos_left - 1,
|
1509
|
+
-1,
|
1510
|
+
]
|
1511
|
+
for c in range(grid_start_col, grid_end_col):
|
1512
|
+
draw_x = self.MT.col_positions[c]
|
1513
|
+
if c and self.width_resizing_enabled:
|
1514
|
+
self.visible_col_dividers[c] = (draw_x - 2, 1, draw_x + 2, yend)
|
1515
|
+
points.extend(
|
1516
|
+
(
|
1517
|
+
draw_x,
|
1518
|
+
-1,
|
1519
|
+
draw_x,
|
1520
|
+
self.current_height,
|
1521
|
+
draw_x,
|
1522
|
+
-1,
|
1523
|
+
self.MT.col_positions[c + 1] if len(self.MT.col_positions) - 1 > c else draw_x,
|
1524
|
+
-1,
|
1525
|
+
)
|
1526
|
+
)
|
1527
|
+
self.redraw_gridline(points=points, fill=self.ops.header_grid_fg, width=1)
|
1528
|
+
|
1519
1529
|
sel_cols_bg = (
|
1520
1530
|
self.ops.header_selected_cells_bg
|
1521
1531
|
if self.ops.header_selected_cells_bg.startswith("#")
|
@@ -1566,7 +1576,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1566
1576
|
self.current_height - 1,
|
1567
1577
|
fill=fill if kwargs["state"] != "disabled" else self.ops.header_grid_fg,
|
1568
1578
|
outline=fill,
|
1569
|
-
tag="dd",
|
1570
1579
|
draw_outline=not dd_drawn,
|
1571
1580
|
draw_arrow=max_width >= 5,
|
1572
1581
|
open_=dd_coords == c,
|
@@ -1601,7 +1610,6 @@ class ColumnHeaders(tk.Canvas):
|
|
1601
1610
|
txt_h + 3,
|
1602
1611
|
fill=fill if kwargs["state"] == "normal" else self.ops.header_grid_fg,
|
1603
1612
|
outline="",
|
1604
|
-
tag="cb",
|
1605
1613
|
draw_check=draw_check,
|
1606
1614
|
)
|
1607
1615
|
if (
|
@@ -1614,22 +1622,22 @@ class ColumnHeaders(tk.Canvas):
|
|
1614
1622
|
text = self.cell_str(datacn, fix=False)
|
1615
1623
|
if not text:
|
1616
1624
|
continue
|
1617
|
-
|
1618
|
-
for wrapped in wrap_text(
|
1625
|
+
gen_lines = wrap_text(
|
1619
1626
|
text=text,
|
1620
1627
|
max_width=max_width,
|
1621
|
-
max_lines=
|
1628
|
+
max_lines=int((self.current_height - top - 2) / txt_h),
|
1622
1629
|
char_width_fn=self.wrap_get_char_w,
|
1623
1630
|
widths=self.MT.char_widths[font],
|
1624
1631
|
wrap=wrap,
|
1625
|
-
)
|
1632
|
+
)
|
1633
|
+
if align[-1] == "w" or align[-1] == "e":
|
1626
1634
|
if self.hidd_text:
|
1627
1635
|
iid, showing = self.hidd_text.popitem()
|
1628
1636
|
self.coords(iid, draw_x, draw_y)
|
1629
1637
|
if showing:
|
1630
1638
|
self.itemconfig(
|
1631
1639
|
iid,
|
1632
|
-
text=
|
1640
|
+
text="\n".join(gen_lines),
|
1633
1641
|
fill=fill,
|
1634
1642
|
font=font,
|
1635
1643
|
anchor=align,
|
@@ -1637,7 +1645,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1637
1645
|
else:
|
1638
1646
|
self.itemconfig(
|
1639
1647
|
iid,
|
1640
|
-
text=
|
1648
|
+
text="\n".join(gen_lines),
|
1641
1649
|
fill=fill,
|
1642
1650
|
font=font,
|
1643
1651
|
anchor=align,
|
@@ -1647,47 +1655,54 @@ class ColumnHeaders(tk.Canvas):
|
|
1647
1655
|
iid = self.create_text(
|
1648
1656
|
draw_x,
|
1649
1657
|
draw_y,
|
1650
|
-
text=
|
1658
|
+
text="\n".join(gen_lines),
|
1651
1659
|
fill=fill,
|
1652
1660
|
font=font,
|
1653
1661
|
anchor=align,
|
1654
|
-
|
1662
|
+
tag="lift",
|
1655
1663
|
)
|
1656
1664
|
self.disp_text[iid] = True
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1665
|
+
else:
|
1666
|
+
for line in gen_lines:
|
1667
|
+
if self.hidd_text:
|
1668
|
+
iid, showing = self.hidd_text.popitem()
|
1669
|
+
self.coords(iid, draw_x, draw_y)
|
1670
|
+
if showing:
|
1671
|
+
self.itemconfig(
|
1672
|
+
iid,
|
1673
|
+
text=line,
|
1674
|
+
fill=fill,
|
1675
|
+
font=font,
|
1676
|
+
anchor=align,
|
1677
|
+
)
|
1678
|
+
else:
|
1679
|
+
self.itemconfig(
|
1680
|
+
iid,
|
1681
|
+
text=line,
|
1682
|
+
fill=fill,
|
1683
|
+
font=font,
|
1684
|
+
anchor=align,
|
1685
|
+
state="normal",
|
1686
|
+
)
|
1687
|
+
else:
|
1688
|
+
iid = self.create_text(
|
1689
|
+
draw_x,
|
1690
|
+
draw_y,
|
1691
|
+
text=line,
|
1692
|
+
fill=fill,
|
1693
|
+
font=font,
|
1694
|
+
anchor=align,
|
1695
|
+
tag="lift",
|
1696
|
+
)
|
1697
|
+
self.disp_text[iid] = True
|
1698
|
+
draw_y += self.MT.header_txt_height
|
1699
|
+
|
1685
1700
|
for dct in (self.hidd_text, self.hidd_high, self.hidd_grid, self.hidd_dropdown, self.hidd_checkbox):
|
1686
1701
|
for iid, showing in dct.items():
|
1687
1702
|
if showing:
|
1688
1703
|
self.itemconfig(iid, state="hidden")
|
1689
1704
|
dct[iid] = False
|
1690
|
-
self.tag_raise("
|
1705
|
+
self.tag_raise("lift")
|
1691
1706
|
if self.disp_resize_lines:
|
1692
1707
|
self.tag_raise("rw")
|
1693
1708
|
return True
|
@@ -317,6 +317,8 @@ class FindWindow(tk.Frame):
|
|
317
317
|
return "break"
|
318
318
|
|
319
319
|
def focus_replace(self, event: tk.Misc = None) -> Literal["break"]:
|
320
|
+
if self.replace_enabled and not self.replace_visible:
|
321
|
+
self.toggle_replace_window()
|
320
322
|
widget = self.focus_get()
|
321
323
|
if widget == self.replace_tktext:
|
322
324
|
self.replace_tktext.select_all()
|