tksheet 7.5.4__tar.gz → 7.5.5__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.5.4/tksheet.egg-info → tksheet-7.5.5}/PKG-INFO +1 -1
- {tksheet-7.5.4 → tksheet-7.5.5}/pyproject.toml +1 -1
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/__init__.py +1 -1
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/functions.py +43 -22
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/row_index.py +6 -1
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/sheet.py +18 -13
- {tksheet-7.5.4 → tksheet-7.5.5/tksheet.egg-info}/PKG-INFO +1 -1
- {tksheet-7.5.4 → tksheet-7.5.5}/LICENSE.txt +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/README.md +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/setup.cfg +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/colors.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/column_headers.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/constants.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/find_window.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/formatters.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/main_table.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/other_classes.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/sheet_options.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/sorting.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/text_editor.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/themes.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/tksheet_types.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet/top_left_rectangle.py +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.5.4 → tksheet-7.5.5}/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 and treeview widget"
|
8
8
|
readme = "README.md"
|
9
|
-
version = "7.5.
|
9
|
+
version = "7.5.5"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -765,6 +765,14 @@ def add_to_displayed(displayed: list[int], to_add: Iterable[int]) -> list[int]:
|
|
765
765
|
return displayed
|
766
766
|
|
767
767
|
|
768
|
+
def push_displayed(displayed: list[int], to_add: Iterable[int]) -> list[int]:
|
769
|
+
# assumes to_add is sorted
|
770
|
+
for i in to_add:
|
771
|
+
ins = bisect_left(displayed, i)
|
772
|
+
displayed[ins:] = [e + 1 for e in islice(displayed, ins, None)]
|
773
|
+
return displayed
|
774
|
+
|
775
|
+
|
768
776
|
def move_elements_by_mapping(
|
769
777
|
seq: list[Any],
|
770
778
|
new_idxs: dict[int, int],
|
@@ -1195,14 +1203,14 @@ PATTERN_ALL = re.compile(r"^:$") # ":"
|
|
1195
1203
|
|
1196
1204
|
def span_a2i(a: str) -> int | None:
|
1197
1205
|
n = 0
|
1198
|
-
for c in a:
|
1206
|
+
for c in a.upper():
|
1199
1207
|
n = n * 26 + ord(c) - ORD_A + 1
|
1200
1208
|
return n - 1
|
1201
1209
|
|
1202
1210
|
|
1203
1211
|
def span_a2n(a: str) -> int | None:
|
1204
1212
|
n = 0
|
1205
|
-
for c in a:
|
1213
|
+
for c in a.upper():
|
1206
1214
|
n = n * 26 + ord(c) - ORD_A + 1
|
1207
1215
|
return n
|
1208
1216
|
|
@@ -1239,7 +1247,7 @@ def key_to_span(
|
|
1239
1247
|
return coords_to_span(widget=widget, from_r=None, from_c=None, upto_r=None, upto_c=None)
|
1240
1248
|
|
1241
1249
|
# Validate input type
|
1242
|
-
elif not isinstance(key, (str, int, slice,
|
1250
|
+
elif not isinstance(key, (str, int, slice, tuple, list)):
|
1243
1251
|
return f"Key type must be either str, int, list, tuple or slice, not '{type(key).__name__}'."
|
1244
1252
|
|
1245
1253
|
try:
|
@@ -1265,22 +1273,34 @@ def key_to_span(
|
|
1265
1273
|
)
|
1266
1274
|
|
1267
1275
|
# Sequence key: various span formats
|
1268
|
-
elif isinstance(key, (
|
1269
|
-
if (
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1276
|
+
elif isinstance(key, (tuple, list)):
|
1277
|
+
if len(key) == 2:
|
1278
|
+
if (isinstance(key[0], int) or key[0] is None) and (isinstance(key[1], int) or key[1] is None):
|
1279
|
+
# Single cell or partial span: (row, col)
|
1280
|
+
r_int = isinstance(key[0], int)
|
1281
|
+
c_int = isinstance(key[1], int)
|
1282
|
+
return span_dict(
|
1283
|
+
from_r=key[0] if r_int else 0,
|
1284
|
+
from_c=key[1] if c_int else 0,
|
1285
|
+
upto_r=key[0] + 1 if r_int else None,
|
1286
|
+
upto_c=key[1] + 1 if c_int else None,
|
1287
|
+
widget=widget,
|
1288
|
+
)
|
1289
|
+
|
1290
|
+
elif isinstance(key[0], int) and isinstance(key[1], str):
|
1291
|
+
# Single cell with column letter: (row 0, col A)
|
1292
|
+
c_int = span_a2i(key[1])
|
1293
|
+
return span_dict(
|
1294
|
+
from_r=key[0],
|
1295
|
+
from_c=c_int,
|
1296
|
+
upto_r=key[0] + 1,
|
1297
|
+
upto_c=c_int + 1,
|
1298
|
+
widget=widget,
|
1299
|
+
)
|
1300
|
+
|
1301
|
+
else:
|
1302
|
+
return f"'{key}' could not be converted to span."
|
1303
|
+
|
1284
1304
|
elif len(key) == 4:
|
1285
1305
|
# Full span coordinates: (from_r, from_c, upto_r, upto_c)
|
1286
1306
|
return coords_to_span(
|
@@ -1290,7 +1310,7 @@ def key_to_span(
|
|
1290
1310
|
upto_r=key[2],
|
1291
1311
|
upto_c=key[3],
|
1292
1312
|
)
|
1293
|
-
elif len(key) == 2 and all(isinstance(k, (
|
1313
|
+
elif len(key) == 2 and all(isinstance(k, (tuple, list)) for k in key):
|
1294
1314
|
# Start and end points: ((from_r, from_c), (upto_r, upto_c))
|
1295
1315
|
return coords_to_span(
|
1296
1316
|
widget=widget,
|
@@ -1327,11 +1347,12 @@ def key_to_span(
|
|
1327
1347
|
widget=widget,
|
1328
1348
|
)
|
1329
1349
|
elif m := PATTERN_COL.match(key):
|
1350
|
+
c_int = span_a2i(m[1])
|
1330
1351
|
return span_dict(
|
1331
1352
|
from_r=None,
|
1332
|
-
from_c=
|
1353
|
+
from_c=c_int,
|
1333
1354
|
upto_r=None,
|
1334
|
-
upto_c=
|
1355
|
+
upto_c=c_int + 1,
|
1335
1356
|
widget=widget,
|
1336
1357
|
)
|
1337
1358
|
elif m := PATTERN_CELL.match(key):
|
@@ -32,6 +32,7 @@ from .functions import (
|
|
32
32
|
mod_event_val,
|
33
33
|
new_tk_event,
|
34
34
|
num2alpha,
|
35
|
+
push_displayed,
|
35
36
|
rounded_box_coords,
|
36
37
|
stored_event_dict,
|
37
38
|
try_b_index,
|
@@ -2632,13 +2633,17 @@ class RowIndex(tk.Canvas):
|
|
2632
2633
|
|
2633
2634
|
# handle displaying the new rows
|
2634
2635
|
event_data["added"]["rows"]["row_heights"] = {}
|
2636
|
+
# parent exists and it's displayed and it's open
|
2635
2637
|
if parent and self.PAR.item_displayed(parent) and parent in self.tree_open_ids:
|
2636
2638
|
self.MT.displayed_rows = add_to_displayed(self.MT.displayed_rows, event_data["added"]["rows"]["index"])
|
2637
2639
|
disp_idx = self.MT.disprn(self.rns[a_node.iid]) # first node, they're contiguous because not undo
|
2638
2640
|
h = self.MT.get_default_row_height()
|
2639
2641
|
for i in range(len(event_data["added"]["rows"]["index"])):
|
2640
2642
|
event_data["added"]["rows"]["row_heights"][disp_idx + i] = h
|
2641
|
-
|
2643
|
+
# parent exists and either it's not displayed or not open
|
2644
|
+
elif parent:
|
2645
|
+
self.MT.displayed_rows = push_displayed(self.MT.displayed_rows, event_data["added"]["rows"]["index"])
|
2646
|
+
# no parent, top level
|
2642
2647
|
elif not parent:
|
2643
2648
|
self.MT.displayed_rows = add_to_displayed(self.MT.displayed_rows, event_data["added"]["rows"]["index"])
|
2644
2649
|
h = self.MT.get_default_row_height()
|
@@ -4746,24 +4746,29 @@ class Sheet(tk.Frame):
|
|
4746
4746
|
|
4747
4747
|
def _get_id_insert_row(self, index: int | None, parent: str) -> int:
|
4748
4748
|
if parent:
|
4749
|
+
chn = self.RI.iid_children(parent)
|
4749
4750
|
if isinstance(index, int):
|
4750
|
-
index = min(index, len(
|
4751
|
-
|
4752
|
-
self.RI.rns[parent]
|
4753
|
-
|
4754
|
-
|
4755
|
-
|
4756
|
-
)
|
4751
|
+
index = min(index, len(chn))
|
4752
|
+
if index == 0:
|
4753
|
+
return self.RI.rns[parent] + 1
|
4754
|
+
else:
|
4755
|
+
prev_chld = chn[index - 1]
|
4756
|
+
return self.RI.rns[prev_chld] + self.RI.num_descendants(prev_chld) + 1
|
4757
4757
|
else:
|
4758
|
-
|
4758
|
+
if chn:
|
4759
|
+
last_chld = chn[-1]
|
4760
|
+
last_chld_rn = self.RI.rns[last_chld]
|
4761
|
+
return last_chld_rn + self.RI.num_descendants(last_chld) + 1
|
4762
|
+
else:
|
4763
|
+
return self.RI.rns[parent] + 1
|
4759
4764
|
else:
|
4760
4765
|
if isinstance(index, int):
|
4761
|
-
|
4762
|
-
|
4763
|
-
|
4766
|
+
if index == 0:
|
4767
|
+
return 0
|
4768
|
+
datarn = self.top_index_row(index)
|
4769
|
+
return len(self.MT._row_index) if datarn is None else datarn
|
4764
4770
|
else:
|
4765
|
-
|
4766
|
-
return datarn
|
4771
|
+
return len(self.MT._row_index)
|
4767
4772
|
|
4768
4773
|
def bulk_insert(
|
4769
4774
|
self,
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|