tksheet 7.4.1__py3-none-any.whl → 7.4.3__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 +2 -1
- tksheet/column_headers.py +3 -3
- tksheet/functions.py +61 -51
- tksheet/main_table.py +42 -42
- tksheet/row_index.py +6 -7
- tksheet/sheet.py +17 -23
- tksheet/sheet_options.py +1 -1
- tksheet/sorting.py +67 -36
- {tksheet-7.4.1.dist-info → tksheet-7.4.3.dist-info}/METADATA +4 -2
- tksheet-7.4.3.dist-info/RECORD +22 -0
- tksheet-7.4.1.dist-info/RECORD +0 -22
- {tksheet-7.4.1.dist-info → tksheet-7.4.3.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.4.1.dist-info → tksheet-7.4.3.dist-info}/WHEEL +0 -0
- {tksheet-7.4.1.dist-info → tksheet-7.4.3.dist-info}/top_level.txt +0 -0
tksheet/__init__.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
tksheet - A Python tkinter table widget
|
5
5
|
"""
|
6
6
|
|
7
|
-
__version__ = "7.4.
|
7
|
+
__version__ = "7.4.3"
|
8
8
|
|
9
9
|
from .colors import (
|
10
10
|
color_map,
|
@@ -93,6 +93,7 @@ from .other_classes import (
|
|
93
93
|
from .row_index import RowIndex
|
94
94
|
from .sheet import Dropdown, Sheet
|
95
95
|
from .sheet_options import new_sheet_options
|
96
|
+
from .sorting import natural_sort_key
|
96
97
|
from .text_editor import (
|
97
98
|
TextEditor,
|
98
99
|
TextEditorTkText,
|
tksheet/column_headers.py
CHANGED
@@ -915,14 +915,14 @@ class ColumnHeaders(tk.Canvas):
|
|
915
915
|
key: Callable | None = None,
|
916
916
|
undo: bool = True,
|
917
917
|
) -> EventDataDict:
|
918
|
-
event_data = self.MT.new_event_dict("
|
918
|
+
event_data = self.MT.new_event_dict("move_rows", state=True)
|
919
919
|
if not self.MT.data:
|
920
920
|
return event_data
|
921
921
|
if column is None:
|
922
922
|
if not self.MT.selected:
|
923
923
|
return event_data
|
924
924
|
column = self.MT.selected.column
|
925
|
-
if try_binding(self.ch_extra_begin_sort_rows_func, event_data, "
|
925
|
+
if try_binding(self.ch_extra_begin_sort_rows_func, event_data, "begin_move_rows"):
|
926
926
|
disp_new_idxs, disp_row_ctr = {}, 0
|
927
927
|
if self.ops.treeview:
|
928
928
|
new_nodes_order, data_new_idxs = sort_tree_view(
|
@@ -973,7 +973,7 @@ class ColumnHeaders(tk.Canvas):
|
|
973
973
|
}
|
974
974
|
if undo and self.MT.undo_enabled:
|
975
975
|
self.MT.undo_stack.append(stored_event_dict(event_data))
|
976
|
-
try_binding(self.ch_extra_end_sort_rows_func, event_data, "
|
976
|
+
try_binding(self.ch_extra_end_sort_rows_func, event_data, "end_move_rows")
|
977
977
|
self.MT.sheet_modified(event_data)
|
978
978
|
self.PAR.emit_event("<<SheetModified>>", event_data)
|
979
979
|
self.MT.refresh()
|
tksheet/functions.py
CHANGED
@@ -8,6 +8,7 @@ import tkinter as tk
|
|
8
8
|
from bisect import bisect_left
|
9
9
|
from collections import deque
|
10
10
|
from collections.abc import Callable, Generator, Hashable, Iterable, Iterator, Sequence
|
11
|
+
from difflib import SequenceMatcher
|
11
12
|
from itertools import islice, repeat
|
12
13
|
from typing import Literal
|
13
14
|
|
@@ -231,50 +232,45 @@ def event_opens_dropdown_or_checkbox(event=None) -> bool:
|
|
231
232
|
)
|
232
233
|
|
233
234
|
|
234
|
-
def dropdown_search_function(
|
235
|
-
search_for
|
236
|
-
data: Sequence[object],
|
237
|
-
) -> None | int:
|
235
|
+
def dropdown_search_function(search_for: str, data: Iterable[object]) -> None | int:
|
236
|
+
search_for = search_for.lower()
|
238
237
|
search_len = len(search_for)
|
239
|
-
|
240
|
-
|
238
|
+
if not search_len:
|
239
|
+
return next((i for i, v in enumerate(data) if not str(v)), None)
|
240
|
+
|
241
|
+
matcher = SequenceMatcher(None, search_for, "", autojunk=False)
|
242
|
+
|
243
|
+
match_rn = None
|
241
244
|
match_st = float("inf")
|
242
245
|
match_len_diff = float("inf")
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
len_diff = len(dd_val) - search_len
|
246
|
+
|
247
|
+
fallback_rn = None
|
248
|
+
fallback_match_length = 0
|
249
|
+
fallback_st = float("inf")
|
250
|
+
|
251
|
+
for rn, value in enumerate(data):
|
252
|
+
value = str(value).lower()
|
253
|
+
if not value:
|
254
|
+
continue
|
255
|
+
st = value.find(search_for)
|
256
|
+
if st != -1:
|
257
|
+
len_diff = len(value) - search_len
|
256
258
|
if st < match_st or (st == match_st and len_diff < match_len_diff):
|
257
259
|
match_rn = rn
|
258
260
|
match_st = st
|
259
261
|
match_len_diff = len_diff
|
260
|
-
|
261
|
-
elif match_rn
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
match_data_numchars = numchars
|
273
|
-
if match_rn != float("inf"):
|
274
|
-
return match_rn
|
275
|
-
elif match_data_rn != float("inf"):
|
276
|
-
return match_data_rn
|
277
|
-
return None
|
262
|
+
|
263
|
+
elif match_rn is None:
|
264
|
+
matcher.set_seq2(value)
|
265
|
+
match = matcher.find_longest_match(0, search_len, 0, len(value))
|
266
|
+
match_length = match.size
|
267
|
+
start = match.b if match_length > 0 else -1
|
268
|
+
if match_length > fallback_match_length or (match_length == fallback_match_length and start < fallback_st):
|
269
|
+
fallback_rn = rn
|
270
|
+
fallback_match_length = match_length
|
271
|
+
fallback_st = start
|
272
|
+
|
273
|
+
return match_rn if match_rn is not None else fallback_rn
|
278
274
|
|
279
275
|
|
280
276
|
def float_to_int(f: int | float) -> int | float:
|
@@ -409,12 +405,22 @@ def push_n(num: int, sorted_seq: Sequence[int]) -> int:
|
|
409
405
|
if num < sorted_seq[0]:
|
410
406
|
return num
|
411
407
|
else:
|
412
|
-
|
413
|
-
|
414
|
-
num
|
415
|
-
|
416
|
-
|
417
|
-
|
408
|
+
if (hi := len(sorted_seq)) < 5:
|
409
|
+
for e in sorted_seq:
|
410
|
+
if num >= e:
|
411
|
+
num += 1
|
412
|
+
else:
|
413
|
+
return num
|
414
|
+
return num
|
415
|
+
else:
|
416
|
+
lo = 0
|
417
|
+
while lo < hi:
|
418
|
+
mid = (lo + hi) // 2
|
419
|
+
if sorted_seq[mid] < num + mid + 1:
|
420
|
+
lo = mid + 1
|
421
|
+
else:
|
422
|
+
hi = mid
|
423
|
+
return num + lo
|
418
424
|
|
419
425
|
|
420
426
|
def get_dropdown_kwargs(
|
@@ -615,14 +621,18 @@ def consecutive_chunks(seq: list[int]) -> Generator[list[int]]:
|
|
615
621
|
|
616
622
|
|
617
623
|
def consecutive_ranges(seq: Sequence[int]) -> Generator[tuple[int, int]]:
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
624
|
+
seq_iter = iter(seq)
|
625
|
+
try:
|
626
|
+
start = next(seq_iter)
|
627
|
+
except StopIteration:
|
628
|
+
return
|
629
|
+
prev = start
|
630
|
+
for curr in seq_iter:
|
631
|
+
if curr > prev + 1:
|
632
|
+
yield start, prev + 1
|
633
|
+
start = curr
|
634
|
+
prev = curr
|
635
|
+
yield start, prev + 1
|
626
636
|
|
627
637
|
|
628
638
|
def is_contiguous(iterable: Iterable[int]) -> bool:
|
tksheet/main_table.py
CHANGED
@@ -1973,7 +1973,7 @@ class MainTable(tk.Canvas):
|
|
1973
1973
|
event_data = self.delete_rows_displayed(
|
1974
1974
|
rows=tuple(reversed(modification["added"]["rows"]["row_heights"])),
|
1975
1975
|
event_data=event_data,
|
1976
|
-
|
1976
|
+
from_undo=True,
|
1977
1977
|
)
|
1978
1978
|
|
1979
1979
|
if modification["added"]["columns"]:
|
@@ -1985,7 +1985,7 @@ class MainTable(tk.Canvas):
|
|
1985
1985
|
event_data = self.delete_columns_displayed(
|
1986
1986
|
cols=tuple(reversed(modification["added"]["columns"]["column_widths"])),
|
1987
1987
|
event_data=event_data,
|
1988
|
-
|
1988
|
+
from_undo=True,
|
1989
1989
|
)
|
1990
1990
|
|
1991
1991
|
if modification["deleted"]["rows"] or modification["deleted"]["row_heights"]:
|
@@ -1998,7 +1998,7 @@ class MainTable(tk.Canvas):
|
|
1998
1998
|
create_ops=False,
|
1999
1999
|
create_selections=False,
|
2000
2000
|
add_col_positions=False,
|
2001
|
-
|
2001
|
+
from_undo=True,
|
2002
2002
|
)
|
2003
2003
|
|
2004
2004
|
if modification["deleted"]["columns"] or modification["deleted"]["column_widths"]:
|
@@ -2010,7 +2010,7 @@ class MainTable(tk.Canvas):
|
|
2010
2010
|
create_ops=False,
|
2011
2011
|
create_selections=False,
|
2012
2012
|
add_row_positions=False,
|
2013
|
-
|
2013
|
+
from_undo=True,
|
2014
2014
|
)
|
2015
2015
|
|
2016
2016
|
if modification["eventname"].startswith(("edit", "move")):
|
@@ -4893,16 +4893,18 @@ class MainTable(tk.Canvas):
|
|
4893
4893
|
add_row_positions: bool = True,
|
4894
4894
|
push_ops: bool = True,
|
4895
4895
|
mod_event_boxes: bool = True,
|
4896
|
-
|
4897
|
-
) -> EventDataDict:
|
4896
|
+
from_undo: bool = False,
|
4897
|
+
) -> EventDataDict | None:
|
4898
|
+
if not from_undo and not try_binding(self.extra_begin_insert_cols_rc_func, event_data, "begin_add_columns"):
|
4899
|
+
return
|
4898
4900
|
self.saved_column_widths = {}
|
4899
|
-
if not
|
4901
|
+
if not from_undo and not self.all_columns_displayed:
|
4900
4902
|
self.displayed_columns = add_to_displayed(self.displayed_columns, columns)
|
4901
4903
|
cws = self.get_column_widths()
|
4902
4904
|
if column_widths and next(reversed(column_widths)) > len(cws):
|
4903
4905
|
for i in reversed(range(len(cws), len(cws) + next(reversed(column_widths)) - len(cws))):
|
4904
4906
|
column_widths[i] = self.PAR.ops.default_column_width
|
4905
|
-
if not
|
4907
|
+
if not from_undo:
|
4906
4908
|
self.set_col_positions(
|
4907
4909
|
itr=insert_items(
|
4908
4910
|
cws,
|
@@ -4928,7 +4930,7 @@ class MainTable(tk.Canvas):
|
|
4928
4930
|
"index": {},
|
4929
4931
|
"row_heights": {rn: default_height for rn in range(len(self.row_positions) - 1, maxrn + 1)},
|
4930
4932
|
}
|
4931
|
-
if not
|
4933
|
+
if not from_undo:
|
4932
4934
|
self.set_row_positions(
|
4933
4935
|
itr=chain(
|
4934
4936
|
self.gen_row_heights(),
|
@@ -4961,9 +4963,11 @@ class MainTable(tk.Canvas):
|
|
4961
4963
|
"header": header,
|
4962
4964
|
"column_widths": column_widths,
|
4963
4965
|
}
|
4966
|
+
if not from_undo:
|
4967
|
+
try_binding(self.extra_end_insert_cols_rc_func, event_data, "end_add_columns")
|
4964
4968
|
return event_data
|
4965
4969
|
|
4966
|
-
def rc_add_columns(self, event: object = None):
|
4970
|
+
def rc_add_columns(self, event: object = None) -> None:
|
4967
4971
|
rowlen = self.equalize_data_row_lengths()
|
4968
4972
|
selcols = sorted(self.get_selected_cols())
|
4969
4973
|
if (
|
@@ -4997,8 +5001,6 @@ class MainTable(tk.Canvas):
|
|
4997
5001
|
if numcols < 1:
|
4998
5002
|
return
|
4999
5003
|
event_data = self.new_event_dict("add_columns", state=True)
|
5000
|
-
if not try_binding(self.extra_begin_insert_cols_rc_func, event_data, "begin_add_columns"):
|
5001
|
-
return
|
5002
5004
|
columns, headers, widths = self.get_args_for_add_columns(data_ins_col, displayed_ins_col, numcols)
|
5003
5005
|
event_data = self.add_columns(
|
5004
5006
|
columns=columns,
|
@@ -5006,11 +5008,11 @@ class MainTable(tk.Canvas):
|
|
5006
5008
|
column_widths=widths,
|
5007
5009
|
event_data=event_data,
|
5008
5010
|
)
|
5009
|
-
if
|
5010
|
-
self.
|
5011
|
-
|
5012
|
-
|
5013
|
-
|
5011
|
+
if event_data:
|
5012
|
+
if self.undo_enabled:
|
5013
|
+
self.undo_stack.append(stored_event_dict(event_data))
|
5014
|
+
self.refresh()
|
5015
|
+
self.sheet_modified(event_data)
|
5014
5016
|
|
5015
5017
|
def add_rows(
|
5016
5018
|
self,
|
@@ -5024,17 +5026,19 @@ class MainTable(tk.Canvas):
|
|
5024
5026
|
push_ops: bool = True,
|
5025
5027
|
tree: bool = True,
|
5026
5028
|
mod_event_boxes: bool = True,
|
5027
|
-
|
5028
|
-
) -> EventDataDict:
|
5029
|
+
from_undo: bool = False,
|
5030
|
+
) -> EventDataDict | None:
|
5031
|
+
if not from_undo and not try_binding(self.extra_begin_insert_rows_rc_func, event_data, "begin_add_rows"):
|
5032
|
+
return
|
5029
5033
|
self.saved_row_heights = {}
|
5030
|
-
if not
|
5034
|
+
if not from_undo and not self.all_rows_displayed:
|
5031
5035
|
self.displayed_rows = add_to_displayed(self.displayed_rows, rows)
|
5032
5036
|
rhs = self.get_row_heights()
|
5033
5037
|
if row_heights and next(reversed(row_heights)) > len(rhs):
|
5034
5038
|
default_row_height = self.get_default_row_height()
|
5035
5039
|
for i in reversed(range(len(rhs), len(rhs) + next(reversed(row_heights)) - len(rhs))):
|
5036
5040
|
row_heights[i] = default_row_height
|
5037
|
-
if not
|
5041
|
+
if not from_undo:
|
5038
5042
|
self.set_row_positions(
|
5039
5043
|
itr=insert_items(
|
5040
5044
|
rhs,
|
@@ -5060,7 +5064,7 @@ class MainTable(tk.Canvas):
|
|
5060
5064
|
"header": {},
|
5061
5065
|
"column_widths": {cn: default_width for cn in range(len(self.col_positions) - 1, maxcn + 1)},
|
5062
5066
|
}
|
5063
|
-
if not
|
5067
|
+
if not from_undo:
|
5064
5068
|
self.set_col_positions(
|
5065
5069
|
itr=chain(
|
5066
5070
|
self.gen_column_widths(),
|
@@ -5093,9 +5097,11 @@ class MainTable(tk.Canvas):
|
|
5093
5097
|
}
|
5094
5098
|
if tree and self.PAR.ops.treeview:
|
5095
5099
|
event_data = self.RI.tree_add_rows(event_data=event_data)
|
5100
|
+
if not from_undo:
|
5101
|
+
try_binding(self.extra_end_insert_rows_rc_func, event_data, "end_add_rows")
|
5096
5102
|
return event_data
|
5097
5103
|
|
5098
|
-
def rc_add_rows(self, event: object = None):
|
5104
|
+
def rc_add_rows(self, event: object = None) -> None:
|
5099
5105
|
total_data_rows = self.total_data_rows()
|
5100
5106
|
selrows = sorted(self.get_selected_rows())
|
5101
5107
|
if (
|
@@ -5129,8 +5135,6 @@ class MainTable(tk.Canvas):
|
|
5129
5135
|
if numrows < 1:
|
5130
5136
|
return
|
5131
5137
|
event_data = self.new_event_dict("add_rows", state=True)
|
5132
|
-
if not try_binding(self.extra_begin_insert_rows_rc_func, event_data, "begin_add_rows"):
|
5133
|
-
return
|
5134
5138
|
rows, index, heights = self.get_args_for_add_rows(data_ins_row, displayed_ins_row, numrows)
|
5135
5139
|
event_data = self.add_rows(
|
5136
5140
|
rows=rows,
|
@@ -5138,11 +5142,11 @@ class MainTable(tk.Canvas):
|
|
5138
5142
|
row_heights=heights,
|
5139
5143
|
event_data=event_data,
|
5140
5144
|
)
|
5141
|
-
if
|
5142
|
-
self.
|
5143
|
-
|
5144
|
-
|
5145
|
-
|
5145
|
+
if event_data:
|
5146
|
+
if self.undo_enabled:
|
5147
|
+
self.undo_stack.append(stored_event_dict(event_data))
|
5148
|
+
self.refresh()
|
5149
|
+
self.sheet_modified(event_data)
|
5146
5150
|
|
5147
5151
|
def get_args_for_add_columns(
|
5148
5152
|
self,
|
@@ -5311,7 +5315,7 @@ class MainTable(tk.Canvas):
|
|
5311
5315
|
self,
|
5312
5316
|
cols: list[int],
|
5313
5317
|
event_data: EventDataDict | None = None,
|
5314
|
-
|
5318
|
+
from_undo: bool = False,
|
5315
5319
|
) -> EventDataDict:
|
5316
5320
|
if not event_data:
|
5317
5321
|
event_data = self.new_event_dict("delete_columns", state=True)
|
@@ -5320,7 +5324,7 @@ class MainTable(tk.Canvas):
|
|
5320
5324
|
for c in reversed(cols):
|
5321
5325
|
if len(self.col_positions) > c + 1:
|
5322
5326
|
event_data["deleted"]["column_widths"][c] = self.col_positions[c + 1] - self.col_positions[c]
|
5323
|
-
if not
|
5327
|
+
if not from_undo:
|
5324
5328
|
cols_set = set(cols)
|
5325
5329
|
self.set_col_positions(
|
5326
5330
|
itr=(width for c, width in enumerate(self.gen_column_widths()) if c not in cols_set)
|
@@ -5334,13 +5338,12 @@ class MainTable(tk.Canvas):
|
|
5334
5338
|
data_indexes: bool = False,
|
5335
5339
|
undo: bool = True,
|
5336
5340
|
emit_event: bool = True,
|
5337
|
-
ext: bool = False,
|
5338
5341
|
) -> EventDataDict:
|
5339
5342
|
event_data = self.new_event_dict("delete_columns", state=True)
|
5340
5343
|
if not columns:
|
5341
5344
|
if not (columns := sorted(self.get_selected_cols())):
|
5342
5345
|
return event_data
|
5343
|
-
if not
|
5346
|
+
if not try_binding(self.extra_begin_del_cols_rc_func, event_data, "begin_delete_columns"):
|
5344
5347
|
return
|
5345
5348
|
if self.all_columns_displayed:
|
5346
5349
|
data_columns = columns
|
@@ -5362,8 +5365,7 @@ class MainTable(tk.Canvas):
|
|
5362
5365
|
)
|
5363
5366
|
if undo and self.undo_enabled:
|
5364
5367
|
self.undo_stack.append(stored_event_dict(event_data))
|
5365
|
-
|
5366
|
-
try_binding(self.extra_end_del_cols_rc_func, event_data, "end_delete_columns")
|
5368
|
+
try_binding(self.extra_end_del_cols_rc_func, event_data, "end_delete_columns")
|
5367
5369
|
if emit_event:
|
5368
5370
|
self.sheet_modified(event_data)
|
5369
5371
|
self.deselect("all")
|
@@ -5400,7 +5402,7 @@ class MainTable(tk.Canvas):
|
|
5400
5402
|
self,
|
5401
5403
|
rows: list[int],
|
5402
5404
|
event_data: EventDataDict | None = None,
|
5403
|
-
|
5405
|
+
from_undo: bool = False,
|
5404
5406
|
) -> EventDataDict:
|
5405
5407
|
if not event_data:
|
5406
5408
|
event_data = self.new_event_dict("delete_rows", state=True)
|
@@ -5409,7 +5411,7 @@ class MainTable(tk.Canvas):
|
|
5409
5411
|
for r in reversed(rows):
|
5410
5412
|
if len(self.row_positions) > r + 1:
|
5411
5413
|
event_data["deleted"]["row_heights"][r] = self.row_positions[r + 1] - self.row_positions[r]
|
5412
|
-
if not
|
5414
|
+
if not from_undo:
|
5413
5415
|
rows_set = set(rows)
|
5414
5416
|
self.set_row_positions(
|
5415
5417
|
itr=(height for r, height in enumerate(self.gen_row_heights()) if r not in rows_set)
|
@@ -5423,13 +5425,12 @@ class MainTable(tk.Canvas):
|
|
5423
5425
|
data_indexes: bool = False,
|
5424
5426
|
undo: bool = True,
|
5425
5427
|
emit_event: bool = True,
|
5426
|
-
ext: bool = False,
|
5427
5428
|
) -> EventDataDict:
|
5428
5429
|
event_data = self.new_event_dict("delete_rows", state=True)
|
5429
5430
|
if not rows:
|
5430
5431
|
if not (rows := sorted(self.get_selected_rows())):
|
5431
5432
|
return
|
5432
|
-
if not
|
5433
|
+
if not try_binding(self.extra_begin_del_rows_rc_func, event_data, "begin_delete_rows"):
|
5433
5434
|
return
|
5434
5435
|
if self.all_rows_displayed:
|
5435
5436
|
data_rows = rows
|
@@ -5462,8 +5463,7 @@ class MainTable(tk.Canvas):
|
|
5462
5463
|
)
|
5463
5464
|
if undo and self.undo_enabled:
|
5464
5465
|
self.undo_stack.append(stored_event_dict(event_data))
|
5465
|
-
|
5466
|
-
try_binding(self.extra_end_del_rows_rc_func, event_data, "end_delete_rows")
|
5466
|
+
try_binding(self.extra_end_del_rows_rc_func, event_data, "end_delete_rows")
|
5467
5467
|
if emit_event:
|
5468
5468
|
self.sheet_modified(event_data)
|
5469
5469
|
self.deselect("all")
|
tksheet/row_index.py
CHANGED
@@ -19,7 +19,6 @@ from .constants import (
|
|
19
19
|
)
|
20
20
|
from .formatters import is_bool_like, try_to_bool
|
21
21
|
from .functions import (
|
22
|
-
consecutive_chunks,
|
23
22
|
consecutive_ranges,
|
24
23
|
del_placeholder_dict_key,
|
25
24
|
event_dict,
|
@@ -686,10 +685,10 @@ class RowIndex(tk.Canvas):
|
|
686
685
|
tag="move_rows",
|
687
686
|
)
|
688
687
|
self.MT.create_resize_line(x1, ypos, x2, ypos, width=3, fill=self.ops.drag_and_drop_bg, tag="move_rows")
|
689
|
-
for
|
688
|
+
for boxst, boxend in consecutive_ranges(rows):
|
690
689
|
self.MT.show_ctrl_outline(
|
691
|
-
start_cell=(0,
|
692
|
-
end_cell=(len(self.MT.col_positions) - 1,
|
690
|
+
start_cell=(0, boxst),
|
691
|
+
end_cell=(len(self.MT.col_positions) - 1, boxend),
|
693
692
|
dash=(),
|
694
693
|
outline=self.ops.drag_and_drop_bg,
|
695
694
|
delete_on_timer=False,
|
@@ -936,14 +935,14 @@ class RowIndex(tk.Canvas):
|
|
936
935
|
key: Callable | None = None,
|
937
936
|
undo: bool = True,
|
938
937
|
) -> EventDataDict:
|
939
|
-
event_data = self.MT.new_event_dict("
|
938
|
+
event_data = self.MT.new_event_dict("move_columns", state=True)
|
940
939
|
if not self.MT.data:
|
941
940
|
return event_data
|
942
941
|
if row is None:
|
943
942
|
if not self.MT.selected:
|
944
943
|
return event_data
|
945
944
|
row = self.MT.selected.row
|
946
|
-
if try_binding(self.ri_extra_begin_sort_cols_func, event_data, "
|
945
|
+
if try_binding(self.ri_extra_begin_sort_cols_func, event_data, "begin_move_columns"):
|
947
946
|
sorted_indices, data_new_idxs = sort_columns_by_row(self.MT.data, row=row, reverse=reverse, key=key)
|
948
947
|
disp_new_idxs = {}
|
949
948
|
if self.MT.all_columns_displayed:
|
@@ -970,7 +969,7 @@ class RowIndex(tk.Canvas):
|
|
970
969
|
}
|
971
970
|
if undo and self.MT.undo_enabled:
|
972
971
|
self.MT.undo_stack.append(stored_event_dict(event_data))
|
973
|
-
try_binding(self.ri_extra_end_sort_cols_func, event_data, "
|
972
|
+
try_binding(self.ri_extra_end_sort_cols_func, event_data, "end_move_columns")
|
974
973
|
self.MT.sheet_modified(event_data)
|
975
974
|
self.PAR.emit_event("<<SheetModified>>", event_data)
|
976
975
|
self.MT.refresh()
|
tksheet/sheet.py
CHANGED
@@ -84,7 +84,7 @@ class Sheet(tk.Frame):
|
|
84
84
|
parent: tk.Misc,
|
85
85
|
name: str = "!sheet",
|
86
86
|
show_table: bool = True,
|
87
|
-
show_top_left: bool =
|
87
|
+
show_top_left: bool | None = None,
|
88
88
|
show_row_index: bool = True,
|
89
89
|
show_header: bool = True,
|
90
90
|
show_x_scrollbar: bool = True,
|
@@ -429,14 +429,18 @@ class Sheet(tk.Frame):
|
|
429
429
|
orient="vertical",
|
430
430
|
style=f"Sheet{self.unique_id}.Vertical.TScrollbar",
|
431
431
|
)
|
432
|
+
self.MT["yscrollcommand"] = self.yscroll.set
|
433
|
+
self.RI["yscrollcommand"] = self.yscroll.set
|
432
434
|
self.xscroll = ttk.Scrollbar(
|
433
435
|
self,
|
434
436
|
command=self.MT._xscrollbar,
|
435
437
|
orient="horizontal",
|
436
438
|
style=f"Sheet{self.unique_id}.Horizontal.TScrollbar",
|
437
439
|
)
|
440
|
+
self.MT["xscrollcommand"] = self.xscroll.set
|
441
|
+
self.CH["xscrollcommand"] = self.xscroll.set
|
438
442
|
self.show()
|
439
|
-
if
|
443
|
+
if show_top_left is False or (show_top_left is None and (not show_row_index or not show_header)):
|
440
444
|
self.hide("top_left")
|
441
445
|
if not show_row_index:
|
442
446
|
self.hide("row_index")
|
@@ -728,9 +732,9 @@ class Sheet(tk.Frame):
|
|
728
732
|
- "begin_rc_delete_column", "begin_delete_columns"
|
729
733
|
- "rc_delete_column", "end_rc_delete_column","end_delete_columns", "delete_columns"
|
730
734
|
- "begin_rc_insert_column", "begin_insert_column", "begin_insert_columns", "begin_add_column","begin_rc_add_column", "begin_add_columns"
|
731
|
-
- "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column", "end_rc_add_column", "end_add_column", "end_add_columns"
|
735
|
+
- "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column", "end_rc_add_column", "end_add_column", "end_add_columns", "add_columns"
|
732
736
|
- "begin_rc_insert_row", "begin_insert_row", "begin_insert_rows", "begin_rc_add_row", "begin_add_row", "begin_add_rows"
|
733
|
-
- "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row", "end_add_row", "end_add_rows"
|
737
|
+
- "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row", "end_add_row", "end_add_rows", "add_rows"
|
734
738
|
- "row_height_resize"
|
735
739
|
- "column_width_resize"
|
736
740
|
- "cell_select"
|
@@ -1031,6 +1035,7 @@ class Sheet(tk.Frame):
|
|
1031
1035
|
"end_rc_add_column",
|
1032
1036
|
"end_add_column",
|
1033
1037
|
"end_add_columns",
|
1038
|
+
"add_columns",
|
1034
1039
|
):
|
1035
1040
|
self.MT.extra_end_insert_cols_rc_func = f
|
1036
1041
|
|
@@ -1052,6 +1057,7 @@ class Sheet(tk.Frame):
|
|
1052
1057
|
"end_rc_add_row",
|
1053
1058
|
"end_add_row",
|
1054
1059
|
"end_add_rows",
|
1060
|
+
"add_rows",
|
1055
1061
|
):
|
1056
1062
|
self.MT.extra_end_insert_rows_rc_func = f
|
1057
1063
|
|
@@ -2328,7 +2334,6 @@ class Sheet(tk.Frame):
|
|
2328
2334
|
data_indexes=data_indexes,
|
2329
2335
|
undo=undo,
|
2330
2336
|
emit_event=emit_event,
|
2331
|
-
ext=True,
|
2332
2337
|
)
|
2333
2338
|
self.set_refresh_timer(redraw)
|
2334
2339
|
return event_data
|
@@ -2350,7 +2355,6 @@ class Sheet(tk.Frame):
|
|
2350
2355
|
data_indexes=data_indexes,
|
2351
2356
|
undo=undo,
|
2352
2357
|
emit_event=emit_event,
|
2353
|
-
ext=True,
|
2354
2358
|
)
|
2355
2359
|
self.set_refresh_timer(redraw)
|
2356
2360
|
return event_data
|
@@ -4365,19 +4369,13 @@ class Sheet(tk.Frame):
|
|
4365
4369
|
self.MT.grid(row=1, column=1, sticky="nswe")
|
4366
4370
|
if canvas in ("all", "row_index", "index"):
|
4367
4371
|
self.RI.grid(row=1, column=0, sticky="nswe")
|
4368
|
-
self.MT["yscrollcommand"] = self.yscroll.set
|
4369
|
-
self.RI["yscrollcommand"] = self.yscroll.set
|
4370
4372
|
self.MT.show_index = True
|
4371
|
-
if self.MT.show_header:
|
4372
|
-
self.show("top_left")
|
4373
4373
|
if canvas in ("all", "header"):
|
4374
4374
|
self.CH.grid(row=0, column=1, sticky="nswe")
|
4375
|
-
self.MT["xscrollcommand"] = self.xscroll.set
|
4376
|
-
self.CH["xscrollcommand"] = self.xscroll.set
|
4377
4375
|
self.MT.show_header = True
|
4378
|
-
|
4379
|
-
|
4380
|
-
|
4376
|
+
if canvas in ("all", "top_left") or (
|
4377
|
+
self.ops.show_top_left is not False and self.MT.show_header and self.MT.show_index
|
4378
|
+
):
|
4381
4379
|
self.TL.grid(row=0, column=0)
|
4382
4380
|
if canvas in ("all", "x_scrollbar"):
|
4383
4381
|
self.xscroll.grid(row=2, column=0, columnspan=2, sticky="nswe")
|
@@ -4405,17 +4403,13 @@ class Sheet(tk.Frame):
|
|
4405
4403
|
) -> Sheet:
|
4406
4404
|
if canvas in ("all", "row_index"):
|
4407
4405
|
self.RI.grid_remove()
|
4408
|
-
self.RI["yscrollcommand"] = 0
|
4409
4406
|
self.MT.show_index = False
|
4410
|
-
if not self.ops.show_top_left:
|
4411
|
-
self.hide("top_left")
|
4412
4407
|
if canvas in ("all", "header"):
|
4413
4408
|
self.CH.grid_remove()
|
4414
|
-
self.CH["xscrollcommand"] = 0
|
4415
4409
|
self.MT.show_header = False
|
4416
|
-
|
4417
|
-
|
4418
|
-
|
4410
|
+
if canvas in ("all", "top_left") or (
|
4411
|
+
not self.ops.show_top_left and (not self.MT.show_index or not self.MT.show_header)
|
4412
|
+
):
|
4419
4413
|
self.TL.grid_remove()
|
4420
4414
|
if canvas in ("all", "x_scrollbar"):
|
4421
4415
|
self.xscroll.grid_remove()
|
@@ -7241,7 +7235,7 @@ class Dropdown(Sheet):
|
|
7241
7235
|
|
7242
7236
|
def search_and_see(self, event: object = None) -> str:
|
7243
7237
|
if self.search_function is not None:
|
7244
|
-
rn = self.search_function(search_for=rf"{event['value']}"
|
7238
|
+
rn = self.search_function(search_for=rf"{event['value']}", data=(r[0] for r in self.MT.data))
|
7245
7239
|
if isinstance(rn, int):
|
7246
7240
|
self.row = rn
|
7247
7241
|
self.see(self.row, 0, redraw=False)
|
tksheet/sheet_options.py
CHANGED
tksheet/sorting.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from collections.abc import Callable, Generator
|
3
|
+
from collections.abc import Callable, Generator, Iterable, Iterator
|
4
4
|
from datetime import datetime
|
5
|
+
from pathlib import Path
|
5
6
|
from re import finditer
|
6
7
|
|
7
|
-
|
8
|
-
from .tksheet_types import AnyIter
|
8
|
+
AnyIter = Iterable | Iterator
|
9
9
|
|
10
10
|
# Possible date formats to try for the entire string
|
11
11
|
date_formats = [
|
@@ -45,24 +45,18 @@ date_formats = [
|
|
45
45
|
]
|
46
46
|
|
47
47
|
|
48
|
-
def natural_sort_key(item: object) -> tuple[int,
|
48
|
+
def natural_sort_key(item: object) -> tuple[int, ...]:
|
49
49
|
"""
|
50
|
-
A key
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
Args:
|
62
|
-
item: Any Python object to be sorted.
|
63
|
-
|
64
|
-
Returns:
|
65
|
-
A tuple or value that can be used for sorting.
|
50
|
+
A key for natural sorting of various Python types.
|
51
|
+
|
52
|
+
0. None
|
53
|
+
1. bool
|
54
|
+
2. int, float
|
55
|
+
3. datetime
|
56
|
+
4. empty strings
|
57
|
+
5. strings (including paths as POSIX strings)
|
58
|
+
6. unknown objects with __str__
|
59
|
+
7. unknown objects
|
66
60
|
"""
|
67
61
|
if item is None:
|
68
62
|
return (0,)
|
@@ -77,26 +71,26 @@ def natural_sort_key(item: object) -> tuple[int, object]:
|
|
77
71
|
return (3, item.timestamp())
|
78
72
|
|
79
73
|
elif isinstance(item, str):
|
74
|
+
if not item:
|
75
|
+
return (4, item)
|
76
|
+
|
80
77
|
for date_format in date_formats:
|
81
78
|
try:
|
82
79
|
return (3, datetime.strptime(item, date_format).timestamp())
|
83
80
|
except ValueError:
|
84
81
|
continue
|
85
|
-
|
86
82
|
try:
|
87
83
|
return (2, float(item))
|
88
84
|
except Exception:
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
return (5, s, n)
|
85
|
+
pass
|
86
|
+
|
87
|
+
return (5, item.lower(), tuple(int(match.group()) for match in finditer(r"\d+", item)))
|
88
|
+
|
89
|
+
elif isinstance(item, Path):
|
90
|
+
posix_str = item.as_posix()
|
91
|
+
return (5, posix_str.lower(), tuple(int(match.group()) for match in finditer(r"\d+", posix_str)))
|
97
92
|
|
98
93
|
else:
|
99
|
-
# For unknown types, attempt to convert to string, or place at end
|
100
94
|
try:
|
101
95
|
return (6, f"{item}".lower())
|
102
96
|
except Exception:
|
@@ -233,11 +227,11 @@ def sort_columns_by_row(
|
|
233
227
|
|
234
228
|
|
235
229
|
def _sort_node_children(
|
236
|
-
node:
|
237
|
-
tree: dict[str,
|
230
|
+
node: object,
|
231
|
+
tree: dict[str, object],
|
238
232
|
reverse: bool,
|
239
233
|
key: Callable,
|
240
|
-
) -> Generator[
|
234
|
+
) -> Generator[object, None, None]:
|
241
235
|
sorted_children = sorted(
|
242
236
|
(tree[child_iid] for child_iid in node.children if child_iid in tree),
|
243
237
|
key=lambda child: key(child.text),
|
@@ -250,12 +244,12 @@ def _sort_node_children(
|
|
250
244
|
|
251
245
|
|
252
246
|
def sort_tree_view(
|
253
|
-
_row_index: list[
|
247
|
+
_row_index: list[object],
|
254
248
|
tree_rns: dict[str, int],
|
255
|
-
tree: dict[str,
|
249
|
+
tree: dict[str, object],
|
256
250
|
key: Callable = natural_sort_key,
|
257
251
|
reverse: bool = False,
|
258
|
-
) -> tuple[list[
|
252
|
+
) -> tuple[list[object], dict[int, int]]:
|
259
253
|
if not _row_index or not tree_rns or not tree:
|
260
254
|
return [], {}
|
261
255
|
|
@@ -285,3 +279,40 @@ def sort_tree_view(
|
|
285
279
|
new_index += 1
|
286
280
|
|
287
281
|
return sorted_nodes, mapping
|
282
|
+
|
283
|
+
|
284
|
+
# def test_natural_sort_key():
|
285
|
+
# test_items = [
|
286
|
+
# None,
|
287
|
+
# False,
|
288
|
+
# True,
|
289
|
+
# 5,
|
290
|
+
# 3.14,
|
291
|
+
# datetime(2023, 1, 1),
|
292
|
+
# "abc123",
|
293
|
+
# "123abc",
|
294
|
+
# "abc123def",
|
295
|
+
# "998zzz",
|
296
|
+
# "10-01-2023",
|
297
|
+
# "01-10-2023",
|
298
|
+
# "fi1le_0.txt",
|
299
|
+
# "file_2.txt",
|
300
|
+
# "file_10.txt",
|
301
|
+
# "file_1.txt",
|
302
|
+
# "path/to/file_2.txt",
|
303
|
+
# "path/to/file_10.txt",
|
304
|
+
# "path/to/file_1.txt",
|
305
|
+
# "/another/path/file_2.log",
|
306
|
+
# "/another/path/file_10.log",
|
307
|
+
# "/another/path/file_1.log",
|
308
|
+
# "C:\\Windows\\System32\\file_2.dll",
|
309
|
+
# "C:\\Windows\\System32\\file_10.dll",
|
310
|
+
# "C:\\Windows\\System32\\file_1.dll",
|
311
|
+
# ]
|
312
|
+
# print("Sort objects:", [natural_sort_key(e) for e in test_items])
|
313
|
+
# sorted_items = sorted(test_items, key=natural_sort_key)
|
314
|
+
# print("\nNatural Sort Order:", sorted_items)
|
315
|
+
|
316
|
+
|
317
|
+
# if __name__ == "__main__":
|
318
|
+
# test_natural_sort_key()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: tksheet
|
3
|
-
Version: 7.4.
|
3
|
+
Version: 7.4.3
|
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
|
@@ -77,7 +77,7 @@ License-File: LICENSE.txt
|
|
77
77
|
<td align="right" colspan="2"><a href="https://github.com/ragardner/tksheet/wiki/Version-7#issues">Issues</a></td>
|
78
78
|
</tr>
|
79
79
|
<tr>
|
80
|
-
<td align="right" colspan="2"><a href="https://github.com/ragardner/tksheet/wiki/Version-7#enhancements-or-suggestions">Suggestions</a></td>
|
80
|
+
<td align="right" colspan="2"><a href="https://github.com/ragardner/tksheet/wiki/Version-7#enhancements-or-suggestions">Suggestions and Contributors</a></td>
|
81
81
|
</tr>
|
82
82
|
</tbody>
|
83
83
|
</table>
|
@@ -101,6 +101,8 @@ License-File: LICENSE.txt
|
|
101
101
|
- [In-built natural sorting](https://github.com/ragardner/tksheet/wiki/Version-7#sorting-the-table)
|
102
102
|
- [Optional built-in find window](https://github.com/ragardner/tksheet/wiki/Version-7#table-functionality-and-bindings)
|
103
103
|
|
104
|
+
Note that due to the limitations of the Tkinter Canvas right-to-left (RTL) languages are not supported.
|
105
|
+
|
104
106
|
```python
|
105
107
|
"""
|
106
108
|
Versions 7+ have succinct and easy to read syntax:
|
@@ -0,0 +1,22 @@
|
|
1
|
+
tksheet/__init__.py,sha256=6xbeTomYvgJaGjRKmHAS1YW24Tmc5ZcR7_YmeyJvDnY,2280
|
2
|
+
tksheet/colors.py,sha256=dHhmdFuQDlwohDHsAfT9VdrKoSl_R33L72a3HCin5zo,51591
|
3
|
+
tksheet/column_headers.py,sha256=ZfHLhXEKe8M9ggf3nzg252DBVH_NRtQichtTF7pisIc,103245
|
4
|
+
tksheet/constants.py,sha256=PkvAtdYXSOiOO5zuxqrObvGIVV2sEE0enN8YLhI8zCc,3922
|
5
|
+
tksheet/find_window.py,sha256=JfkgpGluSng3bKMBneDNQg-AJmBcmCW7JIhtYbSUZaE,8036
|
6
|
+
tksheet/formatters.py,sha256=21ZkMaDIJNUtjvtlAbPl8Y19I9nDxue-JJegw6hblz8,10551
|
7
|
+
tksheet/functions.py,sha256=BDCCKdOUF9FRDq9GF7HmRXaZ22PYRDySlo6WLvyZtVA,52806
|
8
|
+
tksheet/main_table.py,sha256=ChMaI_t5rDwfc5pStG5pxKhqWwKnauJGxa_hoTXq478,357778
|
9
|
+
tksheet/other_classes.py,sha256=ADybikLipEG4NABXx8bGVAovJJhWcomQOWTorzS1CPU,16581
|
10
|
+
tksheet/row_index.py,sha256=R6tCsfXnPbblnSU1tvse_fCjx2DG0U-vx-XaiAPdZs0,133195
|
11
|
+
tksheet/sheet.py,sha256=6hHI_W0rmuV6l2C2jd3fa9pgnNx3kW9k6rY0qqEq-Wg,284585
|
12
|
+
tksheet/sheet_options.py,sha256=7q5T55sZe_elA3MCP0VnbX_f0Euo425aw4uSoPXteoA,9624
|
13
|
+
tksheet/sorting.py,sha256=qLusdRmqDUBkcEgK3WcYbFjIJmXNBoDhR-D2yrWC-BI,9895
|
14
|
+
tksheet/text_editor.py,sha256=ZLVF-0WxDin5qUAJ5r7dmsdwvhyEoxw0PlPvi_AGNPE,7328
|
15
|
+
tksheet/themes.py,sha256=AoNAxibnQi04MN0Zpbn9-kyDnkiiV8TDNWP9FYjpuf0,18473
|
16
|
+
tksheet/tksheet_types.py,sha256=8JQVlA6N9jEZTEAytbcyuhOGuNE4fUPxYhTqoidxEE0,588
|
17
|
+
tksheet/top_left_rectangle.py,sha256=KhTT-rBUwQTgaHjSwL83cL5_71k2L1B7gxkSxZlTSK8,8598
|
18
|
+
tksheet-7.4.3.dist-info/LICENSE.txt,sha256=ndbcCPe9SlHfweE_W2RAueWUe2k7yudyxYLq6WjFdn4,1101
|
19
|
+
tksheet-7.4.3.dist-info/METADATA,sha256=36JytEf6SmrgwlyWLnvv1SLYumrDvxH4wDERw-cxTXE,7839
|
20
|
+
tksheet-7.4.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
21
|
+
tksheet-7.4.3.dist-info/top_level.txt,sha256=my61PXCcck_HHAc9cq3NAlyAr3A3FXxCy9gptEOaCN8,8
|
22
|
+
tksheet-7.4.3.dist-info/RECORD,,
|
tksheet-7.4.1.dist-info/RECORD
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
tksheet/__init__.py,sha256=fR2C-xu9T3nD65tI8sKGFUjapge6Nev2Uy1n_K86b_4,2241
|
2
|
-
tksheet/colors.py,sha256=dHhmdFuQDlwohDHsAfT9VdrKoSl_R33L72a3HCin5zo,51591
|
3
|
-
tksheet/column_headers.py,sha256=kWCK1fTf0poj5vilqxh99r6gJ4-bBaIJfB-oNbH7oE8,103245
|
4
|
-
tksheet/constants.py,sha256=PkvAtdYXSOiOO5zuxqrObvGIVV2sEE0enN8YLhI8zCc,3922
|
5
|
-
tksheet/find_window.py,sha256=JfkgpGluSng3bKMBneDNQg-AJmBcmCW7JIhtYbSUZaE,8036
|
6
|
-
tksheet/formatters.py,sha256=21ZkMaDIJNUtjvtlAbPl8Y19I9nDxue-JJegw6hblz8,10551
|
7
|
-
tksheet/functions.py,sha256=tVwMLWsW4n5M-RCL8DrLMOXygDhBP26wz4nEQq1gkUo,52734
|
8
|
-
tksheet/main_table.py,sha256=mK74o6VlN8EdM6iJt3XyLlJc4DvNGENyjmDJcNEIcX0,357780
|
9
|
-
tksheet/other_classes.py,sha256=ADybikLipEG4NABXx8bGVAovJJhWcomQOWTorzS1CPU,16581
|
10
|
-
tksheet/row_index.py,sha256=F64DrvSBmq89JVhYomSRzyQtS4nWAeWDcqnPL8cgsGI,133222
|
11
|
-
tksheet/sheet.py,sha256=2_fMNnJqwvEkYsrDuyxFC68l6XZROzZVjG2FrSZc7IU,284689
|
12
|
-
tksheet/sheet_options.py,sha256=RAQX9NF8Bvauj4fHW-8TGtZG6cRVSzwGxSUKplg3c28,9625
|
13
|
-
tksheet/sorting.py,sha256=ttjPPJwbYKaiQ_uNDU8hXjPiGkCVeGp2Hfd6SWYIN8w,9181
|
14
|
-
tksheet/text_editor.py,sha256=ZLVF-0WxDin5qUAJ5r7dmsdwvhyEoxw0PlPvi_AGNPE,7328
|
15
|
-
tksheet/themes.py,sha256=AoNAxibnQi04MN0Zpbn9-kyDnkiiV8TDNWP9FYjpuf0,18473
|
16
|
-
tksheet/tksheet_types.py,sha256=8JQVlA6N9jEZTEAytbcyuhOGuNE4fUPxYhTqoidxEE0,588
|
17
|
-
tksheet/top_left_rectangle.py,sha256=KhTT-rBUwQTgaHjSwL83cL5_71k2L1B7gxkSxZlTSK8,8598
|
18
|
-
tksheet-7.4.1.dist-info/LICENSE.txt,sha256=ndbcCPe9SlHfweE_W2RAueWUe2k7yudyxYLq6WjFdn4,1101
|
19
|
-
tksheet-7.4.1.dist-info/METADATA,sha256=bI-Stt1T78UK-_qsUjpFpWxsOHNwULQvAsMadKxP8ak,7717
|
20
|
-
tksheet-7.4.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
21
|
-
tksheet-7.4.1.dist-info/top_level.txt,sha256=my61PXCcck_HHAc9cq3NAlyAr3A3FXxCy9gptEOaCN8,8
|
22
|
-
tksheet-7.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|