tksheet 7.0.5__py3-none-any.whl → 7.1.0__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 +96 -96
- tksheet/column_headers.py +254 -271
- tksheet/functions.py +46 -30
- tksheet/main_table.py +790 -862
- tksheet/other_classes.py +129 -4
- tksheet/row_index.py +473 -319
- tksheet/sheet.py +1027 -232
- tksheet/sheet_options.py +38 -0
- tksheet/text_editor.py +93 -78
- tksheet/themes.py +104 -0
- tksheet/top_left_rectangle.py +2 -2
- tksheet/vars.py +35 -0
- {tksheet-7.0.5.dist-info → tksheet-7.1.0.dist-info}/METADATA +1 -1
- tksheet-7.1.0.dist-info/RECORD +20 -0
- {tksheet-7.0.5.dist-info → tksheet-7.1.0.dist-info}/WHEEL +1 -1
- tksheet-7.0.5.dist-info/RECORD +0 -20
- {tksheet-7.0.5.dist-info → tksheet-7.1.0.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.0.5.dist-info → tksheet-7.1.0.dist-info}/top_level.txt +0 -0
tksheet/sheet.py
CHANGED
@@ -2,9 +2,10 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import tkinter as tk
|
4
4
|
from bisect import bisect_left
|
5
|
-
from collections import deque
|
5
|
+
from collections import defaultdict, deque
|
6
6
|
from collections.abc import Callable, Generator, Iterator, Sequence
|
7
7
|
from itertools import accumulate, chain, islice, product
|
8
|
+
from timeit import default_timer
|
8
9
|
from tkinter import ttk
|
9
10
|
from typing import Literal
|
10
11
|
from warnings import warn as WARNING
|
@@ -13,7 +14,6 @@ from .column_headers import ColumnHeaders
|
|
13
14
|
from .functions import (
|
14
15
|
add_highlight,
|
15
16
|
add_to_options,
|
16
|
-
backwards_compatibility_x,
|
17
17
|
data_to_displayed_idxs,
|
18
18
|
del_from_options,
|
19
19
|
del_named_span_options,
|
@@ -30,20 +30,23 @@ from .functions import (
|
|
30
30
|
is_iterable,
|
31
31
|
key_to_span,
|
32
32
|
num2alpha,
|
33
|
+
pop_positions,
|
33
34
|
set_align,
|
34
35
|
set_readonly,
|
35
36
|
span_froms,
|
36
37
|
span_ranges,
|
37
38
|
tksheet_type_error,
|
39
|
+
unpack,
|
38
40
|
)
|
39
41
|
from .main_table import MainTable
|
40
42
|
from .other_classes import (
|
41
|
-
CurrentlySelectedClass, # noqa: F401
|
42
43
|
DotDict,
|
43
44
|
EventDataDict,
|
44
45
|
FontTuple,
|
45
46
|
GeneratedMouseEvent,
|
47
|
+
Node,
|
46
48
|
Span,
|
49
|
+
Selected,
|
47
50
|
)
|
48
51
|
from .row_index import RowIndex
|
49
52
|
from .sheet_options import (
|
@@ -63,9 +66,11 @@ from .types import (
|
|
63
66
|
)
|
64
67
|
from .vars import (
|
65
68
|
USER_OS,
|
69
|
+
backwards_compatibility_keys,
|
66
70
|
emitted_events,
|
67
71
|
named_span_types,
|
68
72
|
rc_binding,
|
73
|
+
scrollbar_options_keys,
|
69
74
|
)
|
70
75
|
|
71
76
|
|
@@ -98,13 +103,13 @@ class Sheet(tk.Frame):
|
|
98
103
|
total_rows: int | None = None,
|
99
104
|
default_column_width: int = 120,
|
100
105
|
default_header_height: str | int = "1",
|
106
|
+
default_row_index_width: int = 70,
|
101
107
|
default_row_height: str | int = "1",
|
102
108
|
max_column_width: Literal["inf"] | float = "inf",
|
103
109
|
max_row_height: Literal["inf"] | float = "inf",
|
104
110
|
max_header_height: Literal["inf"] | float = "inf",
|
105
111
|
max_index_width: Literal["inf"] | float = "inf",
|
106
112
|
after_redraw_time_ms: int = 20,
|
107
|
-
default_row_index_width: int | None = None,
|
108
113
|
set_all_heights_and_widths: bool = False,
|
109
114
|
zoom: int = 100,
|
110
115
|
align: str = "w",
|
@@ -115,52 +120,6 @@ class Sheet(tk.Frame):
|
|
115
120
|
all_columns_displayed: bool = True,
|
116
121
|
displayed_rows: list[int] = [],
|
117
122
|
all_rows_displayed: bool = True,
|
118
|
-
outline_thickness: int = 0,
|
119
|
-
outline_color: str = theme_light_blue["outline_color"],
|
120
|
-
theme: str = "light blue",
|
121
|
-
frame_bg: str = theme_light_blue["table_bg"],
|
122
|
-
popup_menu_fg: str = theme_light_blue["popup_menu_fg"],
|
123
|
-
popup_menu_bg: str = theme_light_blue["popup_menu_bg"],
|
124
|
-
popup_menu_highlight_bg: str = theme_light_blue["popup_menu_highlight_bg"],
|
125
|
-
popup_menu_highlight_fg: str = theme_light_blue["popup_menu_highlight_fg"],
|
126
|
-
table_grid_fg: str = theme_light_blue["table_grid_fg"],
|
127
|
-
table_bg: str = theme_light_blue["table_bg"],
|
128
|
-
table_fg: str = theme_light_blue["table_fg"],
|
129
|
-
table_selected_box_cells_fg: str = theme_light_blue["table_selected_box_cells_fg"],
|
130
|
-
table_selected_box_rows_fg: str = theme_light_blue["table_selected_box_rows_fg"],
|
131
|
-
table_selected_box_columns_fg: str = theme_light_blue["table_selected_box_columns_fg"],
|
132
|
-
table_selected_cells_border_fg: str = theme_light_blue["table_selected_cells_border_fg"],
|
133
|
-
table_selected_cells_bg: str = theme_light_blue["table_selected_cells_bg"],
|
134
|
-
table_selected_cells_fg: str = theme_light_blue["table_selected_cells_fg"],
|
135
|
-
table_selected_rows_border_fg: str = theme_light_blue["table_selected_rows_border_fg"],
|
136
|
-
table_selected_rows_bg: str = theme_light_blue["table_selected_rows_bg"],
|
137
|
-
table_selected_rows_fg: str = theme_light_blue["table_selected_rows_fg"],
|
138
|
-
table_selected_columns_border_fg: str = theme_light_blue["table_selected_columns_border_fg"],
|
139
|
-
table_selected_columns_bg: str = theme_light_blue["table_selected_columns_bg"],
|
140
|
-
table_selected_columns_fg: str = theme_light_blue["table_selected_columns_fg"],
|
141
|
-
resizing_line_fg: str = theme_light_blue["resizing_line_fg"],
|
142
|
-
drag_and_drop_bg: str = theme_light_blue["drag_and_drop_bg"],
|
143
|
-
index_bg: str = theme_light_blue["index_bg"],
|
144
|
-
index_border_fg: str = theme_light_blue["index_border_fg"],
|
145
|
-
index_grid_fg: str = theme_light_blue["index_grid_fg"],
|
146
|
-
index_fg: str = theme_light_blue["index_fg"],
|
147
|
-
index_selected_cells_bg: str = theme_light_blue["index_selected_cells_bg"],
|
148
|
-
index_selected_cells_fg: str = theme_light_blue["index_selected_cells_fg"],
|
149
|
-
index_selected_rows_bg: str = theme_light_blue["index_selected_rows_bg"],
|
150
|
-
index_selected_rows_fg: str = theme_light_blue["index_selected_rows_fg"],
|
151
|
-
index_hidden_rows_expander_bg: str = theme_light_blue["index_hidden_rows_expander_bg"],
|
152
|
-
header_bg: str = theme_light_blue["header_bg"],
|
153
|
-
header_border_fg: str = theme_light_blue["header_border_fg"],
|
154
|
-
header_grid_fg: str = theme_light_blue["header_grid_fg"],
|
155
|
-
header_fg: str = theme_light_blue["header_fg"],
|
156
|
-
header_selected_cells_bg: str = theme_light_blue["header_selected_cells_bg"],
|
157
|
-
header_selected_cells_fg: str = theme_light_blue["header_selected_cells_fg"],
|
158
|
-
header_selected_columns_bg: str = theme_light_blue["header_selected_columns_bg"],
|
159
|
-
header_selected_columns_fg: str = theme_light_blue["header_selected_columns_fg"],
|
160
|
-
header_hidden_columns_expander_bg: str = theme_light_blue["header_hidden_columns_expander_bg"],
|
161
|
-
top_left_bg: str = theme_light_blue["top_left_bg"],
|
162
|
-
top_left_fg: str = theme_light_blue["top_left_fg"],
|
163
|
-
top_left_fg_highlight: str = theme_light_blue["top_left_fg_highlight"],
|
164
123
|
to_clipboard_delimiter: str = "\t",
|
165
124
|
to_clipboard_quotechar: str = '"',
|
166
125
|
to_clipboard_lineterminator: str = "\n",
|
@@ -174,7 +133,7 @@ class Sheet(tk.Frame):
|
|
174
133
|
show_dropdown_borders: bool = False,
|
175
134
|
arrow_key_down_right_scroll_page: bool = False,
|
176
135
|
cell_auto_resize_enabled: bool = True,
|
177
|
-
auto_resize_row_index: bool =
|
136
|
+
auto_resize_row_index: bool | Literal["empty"] = "empty",
|
178
137
|
auto_resize_columns: int | None = None,
|
179
138
|
auto_resize_rows: int | None = None,
|
180
139
|
set_cell_sizes_on_zoom: bool = False,
|
@@ -210,6 +169,91 @@ class Sheet(tk.Frame):
|
|
210
169
|
show_horizontal_grid: bool = True,
|
211
170
|
display_selected_fg_over_highlights: bool = False,
|
212
171
|
show_selected_cells_border: bool = True,
|
172
|
+
treeview: bool = False,
|
173
|
+
# colors
|
174
|
+
outline_thickness: int = 0,
|
175
|
+
outline_color: str = theme_light_blue["outline_color"],
|
176
|
+
theme: str = "light blue",
|
177
|
+
frame_bg: str = theme_light_blue["table_bg"],
|
178
|
+
popup_menu_fg: str = theme_light_blue["popup_menu_fg"],
|
179
|
+
popup_menu_bg: str = theme_light_blue["popup_menu_bg"],
|
180
|
+
popup_menu_highlight_bg: str = theme_light_blue["popup_menu_highlight_bg"],
|
181
|
+
popup_menu_highlight_fg: str = theme_light_blue["popup_menu_highlight_fg"],
|
182
|
+
table_grid_fg: str = theme_light_blue["table_grid_fg"],
|
183
|
+
table_bg: str = theme_light_blue["table_bg"],
|
184
|
+
table_fg: str = theme_light_blue["table_fg"],
|
185
|
+
table_selected_box_cells_fg: str = theme_light_blue["table_selected_box_cells_fg"],
|
186
|
+
table_selected_box_rows_fg: str = theme_light_blue["table_selected_box_rows_fg"],
|
187
|
+
table_selected_box_columns_fg: str = theme_light_blue["table_selected_box_columns_fg"],
|
188
|
+
table_selected_cells_border_fg: str = theme_light_blue["table_selected_cells_border_fg"],
|
189
|
+
table_selected_cells_bg: str = theme_light_blue["table_selected_cells_bg"],
|
190
|
+
table_selected_cells_fg: str = theme_light_blue["table_selected_cells_fg"],
|
191
|
+
table_selected_rows_border_fg: str = theme_light_blue["table_selected_rows_border_fg"],
|
192
|
+
table_selected_rows_bg: str = theme_light_blue["table_selected_rows_bg"],
|
193
|
+
table_selected_rows_fg: str = theme_light_blue["table_selected_rows_fg"],
|
194
|
+
table_selected_columns_border_fg: str = theme_light_blue["table_selected_columns_border_fg"],
|
195
|
+
table_selected_columns_bg: str = theme_light_blue["table_selected_columns_bg"],
|
196
|
+
table_selected_columns_fg: str = theme_light_blue["table_selected_columns_fg"],
|
197
|
+
resizing_line_fg: str = theme_light_blue["resizing_line_fg"],
|
198
|
+
drag_and_drop_bg: str = theme_light_blue["drag_and_drop_bg"],
|
199
|
+
index_bg: str = theme_light_blue["index_bg"],
|
200
|
+
index_border_fg: str = theme_light_blue["index_border_fg"],
|
201
|
+
index_grid_fg: str = theme_light_blue["index_grid_fg"],
|
202
|
+
index_fg: str = theme_light_blue["index_fg"],
|
203
|
+
index_selected_cells_bg: str = theme_light_blue["index_selected_cells_bg"],
|
204
|
+
index_selected_cells_fg: str = theme_light_blue["index_selected_cells_fg"],
|
205
|
+
index_selected_rows_bg: str = theme_light_blue["index_selected_rows_bg"],
|
206
|
+
index_selected_rows_fg: str = theme_light_blue["index_selected_rows_fg"],
|
207
|
+
index_hidden_rows_expander_bg: str = theme_light_blue["index_hidden_rows_expander_bg"],
|
208
|
+
header_bg: str = theme_light_blue["header_bg"],
|
209
|
+
header_border_fg: str = theme_light_blue["header_border_fg"],
|
210
|
+
header_grid_fg: str = theme_light_blue["header_grid_fg"],
|
211
|
+
header_fg: str = theme_light_blue["header_fg"],
|
212
|
+
header_selected_cells_bg: str = theme_light_blue["header_selected_cells_bg"],
|
213
|
+
header_selected_cells_fg: str = theme_light_blue["header_selected_cells_fg"],
|
214
|
+
header_selected_columns_bg: str = theme_light_blue["header_selected_columns_bg"],
|
215
|
+
header_selected_columns_fg: str = theme_light_blue["header_selected_columns_fg"],
|
216
|
+
header_hidden_columns_expander_bg: str = theme_light_blue["header_hidden_columns_expander_bg"],
|
217
|
+
top_left_bg: str = theme_light_blue["top_left_bg"],
|
218
|
+
top_left_fg: str = theme_light_blue["top_left_fg"],
|
219
|
+
top_left_fg_highlight: str = theme_light_blue["top_left_fg_highlight"],
|
220
|
+
vertical_scroll_background: str = theme_light_blue["vertical_scroll_background"],
|
221
|
+
horizontal_scroll_background: str = theme_light_blue["horizontal_scroll_background"],
|
222
|
+
vertical_scroll_troughcolor: str = theme_light_blue["vertical_scroll_troughcolor"],
|
223
|
+
horizontal_scroll_troughcolor: str = theme_light_blue["horizontal_scroll_troughcolor"],
|
224
|
+
vertical_scroll_lightcolor: str = theme_light_blue["vertical_scroll_lightcolor"],
|
225
|
+
horizontal_scroll_lightcolor: str = theme_light_blue["horizontal_scroll_lightcolor"],
|
226
|
+
vertical_scroll_darkcolor: str = theme_light_blue["vertical_scroll_darkcolor"],
|
227
|
+
horizontal_scroll_darkcolor: str = theme_light_blue["horizontal_scroll_darkcolor"],
|
228
|
+
vertical_scroll_relief: str = theme_light_blue["vertical_scroll_relief"],
|
229
|
+
horizontal_scroll_relief: str = theme_light_blue["horizontal_scroll_relief"],
|
230
|
+
vertical_scroll_troughrelief: str = theme_light_blue["vertical_scroll_troughrelief"],
|
231
|
+
horizontal_scroll_troughrelief: str = theme_light_blue["horizontal_scroll_troughrelief"],
|
232
|
+
vertical_scroll_bordercolor: str = theme_light_blue["vertical_scroll_bordercolor"],
|
233
|
+
horizontal_scroll_bordercolor: str = theme_light_blue["horizontal_scroll_bordercolor"],
|
234
|
+
vertical_scroll_borderwidth: int = 1,
|
235
|
+
horizontal_scroll_borderwidth: int = 1,
|
236
|
+
vertical_scroll_gripcount: int = 0,
|
237
|
+
horizontal_scroll_gripcount: int = 0,
|
238
|
+
vertical_scroll_active_bg: str = theme_light_blue["vertical_scroll_active_bg"],
|
239
|
+
horizontal_scroll_active_bg: str = theme_light_blue["horizontal_scroll_active_bg"],
|
240
|
+
vertical_scroll_not_active_bg: str = theme_light_blue["vertical_scroll_not_active_bg"],
|
241
|
+
horizontal_scroll_not_active_bg: str = theme_light_blue["horizontal_scroll_not_active_bg"],
|
242
|
+
vertical_scroll_pressed_bg: str = theme_light_blue["vertical_scroll_pressed_bg"],
|
243
|
+
horizontal_scroll_pressed_bg: str = theme_light_blue["horizontal_scroll_pressed_bg"],
|
244
|
+
vertical_scroll_active_fg: str = theme_light_blue["vertical_scroll_active_fg"],
|
245
|
+
horizontal_scroll_active_fg: str = theme_light_blue["horizontal_scroll_active_fg"],
|
246
|
+
vertical_scroll_not_active_fg: str = theme_light_blue["vertical_scroll_not_active_fg"],
|
247
|
+
horizontal_scroll_not_active_fg: str = theme_light_blue["horizontal_scroll_not_active_fg"],
|
248
|
+
vertical_scroll_pressed_fg: str = theme_light_blue["vertical_scroll_pressed_fg"],
|
249
|
+
horizontal_scroll_pressed_fg: str = theme_light_blue["horizontal_scroll_pressed_fg"],
|
250
|
+
scrollbar_theme_inheritance: str = "default",
|
251
|
+
scrollbar_show_arrows: bool = True,
|
252
|
+
# changing the arrowsize (width) of the scrollbars
|
253
|
+
# is not working with 'default' theme
|
254
|
+
# use 'clam' theme instead if you want to change the width
|
255
|
+
vertical_scroll_arrowsize: str | int = "",
|
256
|
+
horizontal_scroll_arrowsize: str | int = "",
|
213
257
|
# backwards compatibility
|
214
258
|
column_width: int | None = None,
|
215
259
|
header_height: str | int | None = None,
|
@@ -228,9 +272,19 @@ class Sheet(tk.Frame):
|
|
228
272
|
"There have been many changes from tksheet version 6.x.x to version 7.x.x. Please see the changelog for more information."
|
229
273
|
)
|
230
274
|
self.ops = new_sheet_options()
|
275
|
+
if column_width is not None:
|
276
|
+
default_column_width = column_width
|
277
|
+
if header_height is not None:
|
278
|
+
default_header_height = header_height
|
279
|
+
if row_height is not None:
|
280
|
+
default_row_height = row_height
|
281
|
+
if row_index_width is not None:
|
282
|
+
default_row_index_width = row_index_width
|
283
|
+
if treeview:
|
284
|
+
index_align = "w"
|
285
|
+
auto_resize_row_index = True
|
231
286
|
for k, v in locals().items():
|
232
|
-
xk
|
233
|
-
if xk in self.ops and v != self.ops[xk]:
|
287
|
+
if (xk := backwards_compatibility_keys.get(k, k)) in self.ops and v != self.ops[xk]:
|
234
288
|
self.ops[xk] = v
|
235
289
|
self.ops.from_clipboard_delimiters = (
|
236
290
|
from_clipboard_delimiters
|
@@ -275,10 +329,6 @@ class Sheet(tk.Frame):
|
|
275
329
|
max_header_height=max_header_height,
|
276
330
|
max_row_height=max_row_height,
|
277
331
|
max_index_width=max_index_width,
|
278
|
-
default_row_index_width=default_row_index_width if row_index_width is None else row_index_width,
|
279
|
-
default_header_height=default_header_height if header_height is None else header_height,
|
280
|
-
default_column_width=default_column_width if column_width is None else column_width,
|
281
|
-
default_row_height=default_row_height if row_height is None else row_height,
|
282
332
|
show_index=show_row_index,
|
283
333
|
show_header=show_header,
|
284
334
|
column_headers_canvas=self.CH,
|
@@ -303,8 +353,64 @@ class Sheet(tk.Frame):
|
|
303
353
|
row_index_canvas=self.RI,
|
304
354
|
header_canvas=self.CH,
|
305
355
|
)
|
306
|
-
self.
|
307
|
-
|
356
|
+
self.unique_id = f"{default_timer()}{self.winfo_id()}".replace(".", "")
|
357
|
+
style = ttk.Style()
|
358
|
+
for orientation in ("Vertical", "Horizontal"):
|
359
|
+
style.element_create(
|
360
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar.trough",
|
361
|
+
"from",
|
362
|
+
scrollbar_theme_inheritance,
|
363
|
+
)
|
364
|
+
style.element_create(
|
365
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar.thumb",
|
366
|
+
"from",
|
367
|
+
scrollbar_theme_inheritance,
|
368
|
+
)
|
369
|
+
style.element_create(
|
370
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar.grip",
|
371
|
+
"from",
|
372
|
+
scrollbar_theme_inheritance,
|
373
|
+
)
|
374
|
+
if not scrollbar_show_arrows:
|
375
|
+
style.layout(
|
376
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar",
|
377
|
+
[
|
378
|
+
(
|
379
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar.trough",
|
380
|
+
{
|
381
|
+
"children": [
|
382
|
+
(
|
383
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar.thumb",
|
384
|
+
{
|
385
|
+
"unit": "1",
|
386
|
+
"children": [
|
387
|
+
(
|
388
|
+
f"Sheet{self.unique_id}.{orientation}.TScrollbar.grip",
|
389
|
+
{"sticky": ""},
|
390
|
+
)
|
391
|
+
],
|
392
|
+
"sticky": "nswe",
|
393
|
+
},
|
394
|
+
)
|
395
|
+
],
|
396
|
+
"sticky": "ns" if orientation == "Vertical" else "ew",
|
397
|
+
},
|
398
|
+
)
|
399
|
+
],
|
400
|
+
)
|
401
|
+
self.set_scrollbar_options()
|
402
|
+
self.yscroll = ttk.Scrollbar(
|
403
|
+
self,
|
404
|
+
command=self.MT.set_yviews,
|
405
|
+
orient="vertical",
|
406
|
+
style=f"Sheet{self.unique_id}.Vertical.TScrollbar",
|
407
|
+
)
|
408
|
+
self.xscroll = ttk.Scrollbar(
|
409
|
+
self,
|
410
|
+
command=self.MT.set_xviews,
|
411
|
+
orient="horizontal",
|
412
|
+
style=f"Sheet{self.unique_id}.Horizontal.TScrollbar",
|
413
|
+
)
|
308
414
|
if show_top_left:
|
309
415
|
self.TL.grid(row=0, column=0)
|
310
416
|
if show_table:
|
@@ -1340,9 +1446,11 @@ class Sheet(tk.Frame):
|
|
1340
1446
|
row_heights: bool = True,
|
1341
1447
|
column_widths: bool = True,
|
1342
1448
|
cell_options: bool = True,
|
1449
|
+
tags: bool = True,
|
1343
1450
|
undo_stack: bool = True,
|
1344
1451
|
selections: bool = True,
|
1345
1452
|
sheet_options: bool = False,
|
1453
|
+
tree: bool = True,
|
1346
1454
|
redraw: bool = True,
|
1347
1455
|
) -> Sheet:
|
1348
1456
|
if table:
|
@@ -1352,17 +1460,23 @@ class Sheet(tk.Frame):
|
|
1352
1460
|
if index:
|
1353
1461
|
self.MT._row_index = []
|
1354
1462
|
if row_heights:
|
1463
|
+
self.MT.saved_row_heights = {}
|
1355
1464
|
self.MT.set_row_positions([])
|
1356
1465
|
if column_widths:
|
1466
|
+
self.MT.saved_column_widths = {}
|
1357
1467
|
self.MT.set_col_positions([])
|
1358
1468
|
if cell_options:
|
1359
1469
|
self.reset_all_options()
|
1470
|
+
if tags:
|
1471
|
+
self.MT.reset_tags()
|
1360
1472
|
if undo_stack:
|
1361
1473
|
self.reset_undos()
|
1362
1474
|
if selections:
|
1363
1475
|
self.MT.deselect(redraw=False)
|
1364
1476
|
if sheet_options:
|
1365
1477
|
self.ops = new_sheet_options()
|
1478
|
+
if tree:
|
1479
|
+
self.RI.reset_tree()
|
1366
1480
|
self.set_refresh_timer(redraw)
|
1367
1481
|
return self
|
1368
1482
|
|
@@ -1467,7 +1581,7 @@ class Sheet(tk.Frame):
|
|
1467
1581
|
event_data = event_dict(
|
1468
1582
|
name="edit_table",
|
1469
1583
|
sheet=self.name,
|
1470
|
-
selected=self.MT.
|
1584
|
+
selected=self.MT.selected,
|
1471
1585
|
)
|
1472
1586
|
set_t = self.event_data_set_table_cell
|
1473
1587
|
set_i, set_h = self.event_data_set_index_cell, self.event_data_set_header_cell
|
@@ -1697,7 +1811,7 @@ class Sheet(tk.Frame):
|
|
1697
1811
|
event_data = event_dict(
|
1698
1812
|
name="edit_table",
|
1699
1813
|
sheet=self.name,
|
1700
|
-
selected=self.MT.
|
1814
|
+
selected=self.MT.selected,
|
1701
1815
|
)
|
1702
1816
|
if index:
|
1703
1817
|
for r in rows:
|
@@ -1808,6 +1922,7 @@ class Sheet(tk.Frame):
|
|
1808
1922
|
fill: bool = True,
|
1809
1923
|
undo: bool = False,
|
1810
1924
|
emit_event: bool = False,
|
1925
|
+
create_selections: bool = True,
|
1811
1926
|
redraw: bool = True,
|
1812
1927
|
) -> EventDataDict:
|
1813
1928
|
total_cols = None
|
@@ -1870,8 +1985,9 @@ class Sheet(tk.Frame):
|
|
1870
1985
|
name="add_rows",
|
1871
1986
|
sheet=self.name,
|
1872
1987
|
boxes=self.MT.get_boxes(),
|
1873
|
-
selected=self.MT.
|
1988
|
+
selected=self.MT.selected,
|
1874
1989
|
),
|
1990
|
+
create_selections=create_selections,
|
1875
1991
|
)
|
1876
1992
|
if undo:
|
1877
1993
|
self.MT.undo_stack.append(ev_stack_dict(event_data))
|
@@ -1889,6 +2005,7 @@ class Sheet(tk.Frame):
|
|
1889
2005
|
fill: bool = True,
|
1890
2006
|
undo: bool = False,
|
1891
2007
|
emit_event: bool = False,
|
2008
|
+
create_selections: bool = True,
|
1892
2009
|
redraw: bool = True,
|
1893
2010
|
) -> EventDataDict:
|
1894
2011
|
old_total = self.MT.equalize_data_row_lengths()
|
@@ -1959,8 +2076,9 @@ class Sheet(tk.Frame):
|
|
1959
2076
|
name="add_columns",
|
1960
2077
|
sheet=self.name,
|
1961
2078
|
boxes=self.MT.get_boxes(),
|
1962
|
-
selected=self.MT.
|
2079
|
+
selected=self.MT.selected,
|
1963
2080
|
),
|
2081
|
+
create_selections=create_selections,
|
1964
2082
|
)
|
1965
2083
|
if undo:
|
1966
2084
|
self.MT.undo_stack.append(ev_stack_dict(event_data))
|
@@ -2018,7 +2136,7 @@ class Sheet(tk.Frame):
|
|
2018
2136
|
name="delete_rows",
|
2019
2137
|
sheet=self.name,
|
2020
2138
|
boxes=self.MT.get_boxes(),
|
2021
|
-
selected=self.MT.
|
2139
|
+
selected=self.MT.selected,
|
2022
2140
|
)
|
2023
2141
|
if not data_indexes:
|
2024
2142
|
event_data = self.MT.delete_rows_displayed(rows, event_data)
|
@@ -2059,7 +2177,7 @@ class Sheet(tk.Frame):
|
|
2059
2177
|
name="delete_columns",
|
2060
2178
|
sheet=self.name,
|
2061
2179
|
boxes=self.MT.get_boxes(),
|
2062
|
-
selected=self.MT.
|
2180
|
+
selected=self.MT.selected,
|
2063
2181
|
)
|
2064
2182
|
if not data_indexes:
|
2065
2183
|
event_data = self.MT.delete_columns_displayed(columns, event_data)
|
@@ -2116,7 +2234,7 @@ class Sheet(tk.Frame):
|
|
2116
2234
|
raise ValueError("number argument must be integer and > 0")
|
2117
2235
|
if number > len(self.MT.data):
|
2118
2236
|
if mod_positions:
|
2119
|
-
height = self.MT.
|
2237
|
+
height = self.MT.get_default_row_height()
|
2120
2238
|
for r in range(number - len(self.MT.data)):
|
2121
2239
|
self.MT.insert_row_position("end", height)
|
2122
2240
|
elif number < len(self.MT.data):
|
@@ -2140,7 +2258,7 @@ class Sheet(tk.Frame):
|
|
2140
2258
|
raise ValueError("number argument must be integer and > 0")
|
2141
2259
|
if number > total_cols:
|
2142
2260
|
if mod_positions:
|
2143
|
-
width = self.
|
2261
|
+
width = self.ops.default_column_width
|
2144
2262
|
for c in range(number - total_cols):
|
2145
2263
|
self.MT.insert_col_position("end", width)
|
2146
2264
|
elif number < total_cols:
|
@@ -2254,7 +2372,7 @@ class Sheet(tk.Frame):
|
|
2254
2372
|
data_idxs, disp_idxs, event_data = self.MT.move_rows_adjust_options_dict(
|
2255
2373
|
data_new_idxs=data_new_idxs,
|
2256
2374
|
data_old_idxs=dict(zip(data_new_idxs.values(), data_new_idxs)),
|
2257
|
-
|
2375
|
+
totalrows=None,
|
2258
2376
|
disp_new_idxs=disp_new_idxs,
|
2259
2377
|
move_data=move_data,
|
2260
2378
|
create_selections=create_selections,
|
@@ -2398,11 +2516,11 @@ class Sheet(tk.Frame):
|
|
2398
2516
|
) -> Span:
|
2399
2517
|
span = self.span_from_key(*key)
|
2400
2518
|
if span.table:
|
2401
|
-
self.MT.
|
2519
|
+
self.MT.hide_dropdown_window()
|
2402
2520
|
if span.index:
|
2403
|
-
self.RI.
|
2521
|
+
self.RI.hide_dropdown_window()
|
2404
2522
|
if span.header:
|
2405
|
-
self.CH.
|
2523
|
+
self.CH.hide_dropdown_window()
|
2406
2524
|
self.del_options_using_span(span, "dropdown")
|
2407
2525
|
self.set_refresh_timer(redraw)
|
2408
2526
|
return span
|
@@ -2789,8 +2907,14 @@ class Sheet(tk.Frame):
|
|
2789
2907
|
|
2790
2908
|
# Getting Selected Cells
|
2791
2909
|
|
2792
|
-
def get_currently_selected(self) -> tuple[()] |
|
2793
|
-
|
2910
|
+
def get_currently_selected(self) -> tuple[()] | Selected:
|
2911
|
+
# if self.MT.selected:
|
2912
|
+
# return self.MT.selected._replace(type_=self.MT.selected.type_[:-1])
|
2913
|
+
return self.MT.selected
|
2914
|
+
|
2915
|
+
@property
|
2916
|
+
def selected(self) -> tuple[()] | Selected:
|
2917
|
+
return self.MT.selected
|
2794
2918
|
|
2795
2919
|
def get_selected_rows(
|
2796
2920
|
self,
|
@@ -3057,31 +3181,18 @@ class Sheet(tk.Frame):
|
|
3057
3181
|
|
3058
3182
|
def default_column_width(self, width: int | None = None) -> int:
|
3059
3183
|
if isinstance(width, int):
|
3060
|
-
|
3061
|
-
|
3062
|
-
else:
|
3063
|
-
self.MT.default_column_width = int(width)
|
3064
|
-
return self.MT.default_column_width
|
3184
|
+
self.ops.default_column_width = width
|
3185
|
+
return self.ops.default_column_width
|
3065
3186
|
|
3066
3187
|
def default_row_height(self, height: int | str | None = None) -> int:
|
3067
|
-
if height
|
3068
|
-
self.
|
3069
|
-
|
3070
|
-
height if isinstance(height, int) else self.MT.get_lines_cell_height(int(height)),
|
3071
|
-
)
|
3072
|
-
return self.MT.default_row_height[1]
|
3188
|
+
if isinstance(height, (int, str)):
|
3189
|
+
self.ops.default_row_height = height
|
3190
|
+
return self.ops.default_row_height
|
3073
3191
|
|
3074
3192
|
def default_header_height(self, height: int | str | None = None) -> int:
|
3075
|
-
if height
|
3076
|
-
self.
|
3077
|
-
|
3078
|
-
(
|
3079
|
-
height
|
3080
|
-
if isinstance(height, int)
|
3081
|
-
else self.MT.get_lines_cell_height(int(height), font=self.ops.header_font)
|
3082
|
-
),
|
3083
|
-
)
|
3084
|
-
return self.MT.default_header_height[1]
|
3193
|
+
if isinstance(height, (int, str)):
|
3194
|
+
self.ops.default_header_height = height
|
3195
|
+
return self.ops.default_header_height
|
3085
3196
|
|
3086
3197
|
def set_cell_size_to_text(
|
3087
3198
|
self,
|
@@ -3189,7 +3300,7 @@ class Sheet(tk.Frame):
|
|
3189
3300
|
canvas_positions: bool = False,
|
3190
3301
|
reset: bool = False,
|
3191
3302
|
) -> Sheet:
|
3192
|
-
if reset:
|
3303
|
+
if reset or column_widths is None:
|
3193
3304
|
self.MT.reset_col_positions()
|
3194
3305
|
elif is_iterable(column_widths):
|
3195
3306
|
if canvas_positions and isinstance(column_widths, list):
|
@@ -3204,9 +3315,9 @@ class Sheet(tk.Frame):
|
|
3204
3315
|
canvas_positions: bool = False,
|
3205
3316
|
reset: bool = False,
|
3206
3317
|
) -> Sheet:
|
3207
|
-
if reset:
|
3318
|
+
if reset or row_heights is None:
|
3208
3319
|
self.MT.reset_row_positions()
|
3209
|
-
|
3320
|
+
elif is_iterable(row_heights):
|
3210
3321
|
if canvas_positions and isinstance(row_heights, list):
|
3211
3322
|
self.MT.row_positions = row_heights
|
3212
3323
|
else:
|
@@ -3308,10 +3419,10 @@ class Sheet(tk.Frame):
|
|
3308
3419
|
if total_rows is None and total_columns is None:
|
3309
3420
|
return len(self.MT.row_positions) - 1, len(self.MT.col_positions) - 1
|
3310
3421
|
if isinstance(total_rows, int):
|
3311
|
-
height = self.MT.
|
3422
|
+
height = self.MT.get_default_row_height()
|
3312
3423
|
self.MT.row_positions = list(accumulate(chain([0], (height for row in range(total_rows)))))
|
3313
3424
|
if isinstance(total_columns, int):
|
3314
|
-
width = self.
|
3425
|
+
width = self.ops.default_column_width
|
3315
3426
|
self.MT.col_positions = list(accumulate(chain([0], (width for column in range(total_columns)))))
|
3316
3427
|
return self
|
3317
3428
|
|
@@ -3324,13 +3435,13 @@ class Sheet(tk.Frame):
|
|
3324
3435
|
return self
|
3325
3436
|
|
3326
3437
|
def get_example_canvas_column_widths(self, total_cols: int | None = None) -> list[float]:
|
3327
|
-
colpos = int(self.
|
3438
|
+
colpos = int(self.ops.default_column_width)
|
3328
3439
|
if isinstance(total_cols, int):
|
3329
3440
|
return list(accumulate(chain([0], (colpos for c in range(total_cols)))))
|
3330
3441
|
return list(accumulate(chain([0], (colpos for c in range(len(self.MT.col_positions) - 1)))))
|
3331
3442
|
|
3332
3443
|
def get_example_canvas_row_heights(self, total_rows: int | None = None) -> list[float]:
|
3333
|
-
rowpos = self.MT.
|
3444
|
+
rowpos = self.MT.get_default_row_height()
|
3334
3445
|
if isinstance(total_rows, int):
|
3335
3446
|
return list(accumulate(chain([0], (rowpos for c in range(total_rows)))))
|
3336
3447
|
return list(accumulate(chain([0], (rowpos for c in range(len(self.MT.row_positions) - 1)))))
|
@@ -3457,15 +3568,25 @@ class Sheet(tk.Frame):
|
|
3457
3568
|
def cell_completely_visible(self, r: int, c: int, seperate_axes: bool = False) -> bool:
|
3458
3569
|
return self.MT.cell_completely_visible(r, c, seperate_axes)
|
3459
3570
|
|
3460
|
-
def set_xview(self, position: float, option: str = "moveto") -> Sheet:
|
3461
|
-
|
3462
|
-
|
3571
|
+
def set_xview(self, position: None | float = None, option: str = "moveto") -> Sheet | tuple[float, float]:
|
3572
|
+
if position is not None:
|
3573
|
+
self.MT.set_xviews(option, position)
|
3574
|
+
return self
|
3575
|
+
return self.MT.xview()
|
3463
3576
|
|
3464
|
-
|
3465
|
-
|
3466
|
-
|
3577
|
+
xview = set_xview
|
3578
|
+
xview_moveto = set_xview
|
3579
|
+
|
3580
|
+
def set_yview(self, position: None | float = None, option: str = "moveto") -> Sheet | tuple[float, float]:
|
3581
|
+
if position is not None:
|
3582
|
+
self.MT.set_yviews(option, position)
|
3583
|
+
return self
|
3584
|
+
return self.MT.yview()
|
3585
|
+
|
3586
|
+
yview = set_yview
|
3587
|
+
yview_moveto = set_yview
|
3467
3588
|
|
3468
|
-
def set_view(self, x_args: [str, float], y_args: [str, float]) -> Sheet:
|
3589
|
+
def set_view(self, x_args: list[str, float], y_args: list[str, float]) -> Sheet:
|
3469
3590
|
self.MT.set_view(x_args, y_args)
|
3470
3591
|
return self
|
3471
3592
|
|
@@ -3480,6 +3601,8 @@ class Sheet(tk.Frame):
|
|
3480
3601
|
def displayed_column_to_data(self, c: int) -> int:
|
3481
3602
|
return c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
|
3482
3603
|
|
3604
|
+
data_c = displayed_column_to_data
|
3605
|
+
|
3483
3606
|
def display_columns(
|
3484
3607
|
self,
|
3485
3608
|
columns: None | Literal["all"] | Iterator[int] = None,
|
@@ -3504,31 +3627,70 @@ class Sheet(tk.Frame):
|
|
3504
3627
|
self.set_refresh_timer(redraw if redraw else refresh)
|
3505
3628
|
return res
|
3506
3629
|
|
3507
|
-
# uses displayed indexes
|
3508
3630
|
def hide_columns(
|
3509
3631
|
self,
|
3510
|
-
columns: int | set | Iterator[int]
|
3632
|
+
columns: int | set[int] | Iterator[int],
|
3511
3633
|
redraw: bool = True,
|
3512
3634
|
deselect_all: bool = True,
|
3635
|
+
data_indexes: bool = False,
|
3513
3636
|
) -> Sheet:
|
3514
3637
|
if isinstance(columns, int):
|
3515
|
-
|
3516
|
-
elif isinstance(columns, set):
|
3517
|
-
|
3518
|
-
|
3519
|
-
|
3520
|
-
if not _columns:
|
3521
|
-
return
|
3638
|
+
columns = {columns}
|
3639
|
+
elif not isinstance(columns, set):
|
3640
|
+
columns = set(columns)
|
3641
|
+
if not columns:
|
3642
|
+
return
|
3522
3643
|
if self.MT.all_columns_displayed:
|
3523
|
-
|
3644
|
+
self.MT.displayed_columns = [c for c in range(self.MT.total_data_cols()) if c not in columns]
|
3645
|
+
to_pop = {c: c for c in columns}
|
3524
3646
|
else:
|
3525
|
-
|
3526
|
-
|
3527
|
-
|
3528
|
-
|
3529
|
-
|
3530
|
-
|
3647
|
+
to_pop = {}
|
3648
|
+
new_disp = []
|
3649
|
+
if data_indexes:
|
3650
|
+
for i, c in enumerate(self.MT.displayed_columns):
|
3651
|
+
if c not in columns:
|
3652
|
+
new_disp.append(c)
|
3653
|
+
else:
|
3654
|
+
to_pop[i] = c
|
3655
|
+
else:
|
3656
|
+
for i, c in enumerate(self.MT.displayed_columns):
|
3657
|
+
if i not in columns:
|
3658
|
+
new_disp.append(c)
|
3659
|
+
else:
|
3660
|
+
to_pop[i] = c
|
3661
|
+
self.MT.displayed_columns = new_disp
|
3662
|
+
self.MT.all_columns_displayed = False
|
3663
|
+
self.MT.set_col_positions(
|
3664
|
+
pop_positions(
|
3665
|
+
itr=self.MT.gen_column_widths,
|
3666
|
+
to_pop=to_pop,
|
3667
|
+
save_to=self.MT.saved_column_widths,
|
3668
|
+
),
|
3531
3669
|
)
|
3670
|
+
if deselect_all:
|
3671
|
+
self.MT.deselect(redraw=False)
|
3672
|
+
self.set_refresh_timer(redraw)
|
3673
|
+
return self
|
3674
|
+
|
3675
|
+
# uses data indexes
|
3676
|
+
def show_columns(
|
3677
|
+
self,
|
3678
|
+
columns: int | Iterator[int],
|
3679
|
+
redraw: bool = True,
|
3680
|
+
deselect_all: bool = True,
|
3681
|
+
) -> Sheet:
|
3682
|
+
if isinstance(columns, int):
|
3683
|
+
columns = [columns]
|
3684
|
+
cws = self.MT.get_column_widths()
|
3685
|
+
for column in columns:
|
3686
|
+
idx = bisect_left(self.MT.displayed_columns, column)
|
3687
|
+
if len(self.MT.displayed_columns) == idx or self.MT.displayed_columns[idx] != column:
|
3688
|
+
self.MT.displayed_columns.insert(idx, column)
|
3689
|
+
cws.insert(idx, self.MT.saved_column_widths.pop(column, self.PAR.ops.default_column_width))
|
3690
|
+
self.MT.set_col_positions(cws)
|
3691
|
+
if deselect_all:
|
3692
|
+
self.MT.deselect(redraw=False)
|
3693
|
+
self.set_refresh_timer(redraw)
|
3532
3694
|
return self
|
3533
3695
|
|
3534
3696
|
def all_columns_displayed(self, a: bool | None = None) -> bool:
|
@@ -3546,6 +3708,8 @@ class Sheet(tk.Frame):
|
|
3546
3708
|
def displayed_row_to_data(self, r: int) -> int:
|
3547
3709
|
return r if self.MT.all_rows_displayed else self.MT.displayed_rows[r]
|
3548
3710
|
|
3711
|
+
data_r = displayed_row_to_data
|
3712
|
+
|
3549
3713
|
def display_rows(
|
3550
3714
|
self,
|
3551
3715
|
rows: None | Literal["all"] | Iterator[int] = None,
|
@@ -3568,31 +3732,70 @@ class Sheet(tk.Frame):
|
|
3568
3732
|
self.set_refresh_timer(redraw if redraw else refresh)
|
3569
3733
|
return res
|
3570
3734
|
|
3571
|
-
# uses displayed indexes
|
3572
3735
|
def hide_rows(
|
3573
3736
|
self,
|
3574
|
-
rows: int | set | Iterator[int]
|
3737
|
+
rows: int | set[int] | Iterator[int],
|
3575
3738
|
redraw: bool = True,
|
3576
3739
|
deselect_all: bool = True,
|
3740
|
+
data_indexes: bool = False,
|
3577
3741
|
) -> Sheet:
|
3578
3742
|
if isinstance(rows, int):
|
3579
|
-
|
3580
|
-
elif isinstance(rows, set):
|
3581
|
-
|
3582
|
-
|
3583
|
-
|
3584
|
-
if not _rows:
|
3585
|
-
return
|
3743
|
+
rows = {rows}
|
3744
|
+
elif not isinstance(rows, set):
|
3745
|
+
rows = set(rows)
|
3746
|
+
if not rows:
|
3747
|
+
return
|
3586
3748
|
if self.MT.all_rows_displayed:
|
3587
|
-
|
3749
|
+
self.MT.displayed_rows = [r for r in range(self.MT.total_data_rows()) if r not in rows]
|
3750
|
+
to_pop = {r: r for r in rows}
|
3588
3751
|
else:
|
3589
|
-
|
3590
|
-
|
3591
|
-
|
3592
|
-
|
3593
|
-
|
3594
|
-
|
3752
|
+
to_pop = {}
|
3753
|
+
new_disp = []
|
3754
|
+
if data_indexes:
|
3755
|
+
for i, r in enumerate(self.MT.displayed_rows):
|
3756
|
+
if r not in rows:
|
3757
|
+
new_disp.append(r)
|
3758
|
+
else:
|
3759
|
+
to_pop[i] = r
|
3760
|
+
else:
|
3761
|
+
for i, r in enumerate(self.MT.displayed_rows):
|
3762
|
+
if i not in rows:
|
3763
|
+
new_disp.append(r)
|
3764
|
+
else:
|
3765
|
+
to_pop[i] = r
|
3766
|
+
self.MT.displayed_rows = new_disp
|
3767
|
+
self.MT.all_rows_displayed = False
|
3768
|
+
self.MT.set_row_positions(
|
3769
|
+
pop_positions(
|
3770
|
+
itr=self.MT.gen_row_heights,
|
3771
|
+
to_pop=to_pop,
|
3772
|
+
save_to=self.MT.saved_row_heights,
|
3773
|
+
),
|
3595
3774
|
)
|
3775
|
+
if deselect_all:
|
3776
|
+
self.MT.deselect(redraw=False)
|
3777
|
+
self.set_refresh_timer(redraw)
|
3778
|
+
return self
|
3779
|
+
|
3780
|
+
# uses data indexes
|
3781
|
+
def show_rows(
|
3782
|
+
self,
|
3783
|
+
rows: int | Iterator[int],
|
3784
|
+
redraw: bool = True,
|
3785
|
+
deselect_all: bool = True,
|
3786
|
+
) -> Sheet:
|
3787
|
+
if isinstance(rows, int):
|
3788
|
+
rows = [rows]
|
3789
|
+
rhs = self.MT.get_row_heights()
|
3790
|
+
for row in rows:
|
3791
|
+
idx = bisect_left(self.MT.displayed_rows, row)
|
3792
|
+
if len(self.MT.displayed_rows) == idx or self.MT.displayed_rows[idx] != row:
|
3793
|
+
self.MT.displayed_rows.insert(idx, row)
|
3794
|
+
rhs.insert(idx, self.MT.saved_row_heights.pop(row, self.MT.get_default_row_height()))
|
3795
|
+
self.MT.set_row_positions(rhs)
|
3796
|
+
if deselect_all:
|
3797
|
+
self.MT.deselect(redraw=False)
|
3798
|
+
self.set_refresh_timer(redraw)
|
3596
3799
|
return self
|
3597
3800
|
|
3598
3801
|
def all_rows_displayed(self, a: bool | None = None) -> bool:
|
@@ -3744,22 +3947,34 @@ class Sheet(tk.Frame):
|
|
3744
3947
|
def set_text_editor_value(
|
3745
3948
|
self,
|
3746
3949
|
text: str = "",
|
3747
|
-
r: int | None = None,
|
3748
|
-
c: int | None = None,
|
3749
3950
|
) -> Sheet:
|
3750
|
-
if self.MT.text_editor
|
3751
|
-
self.MT.text_editor.set_text(text)
|
3752
|
-
|
3753
|
-
|
3951
|
+
if self.MT.text_editor.open:
|
3952
|
+
self.MT.text_editor.window.set_text(text)
|
3953
|
+
return self
|
3954
|
+
|
3955
|
+
def set_index_text_editor_value(
|
3956
|
+
self,
|
3957
|
+
text: str = "",
|
3958
|
+
) -> Sheet:
|
3959
|
+
if self.RI.text_editor.open:
|
3960
|
+
self.RI.text_editor.window.set_text(text)
|
3961
|
+
return self
|
3962
|
+
|
3963
|
+
def set_header_text_editor_value(
|
3964
|
+
self,
|
3965
|
+
text: str = "",
|
3966
|
+
) -> Sheet:
|
3967
|
+
if self.CH.text_editor.open:
|
3968
|
+
self.CH.text_editor.window.set_text(text)
|
3754
3969
|
return self
|
3755
3970
|
|
3756
3971
|
def destroy_text_editor(self, event: object = None) -> Sheet:
|
3757
|
-
self.MT.
|
3972
|
+
self.MT.hide_text_editor(event=event)
|
3758
3973
|
return self
|
3759
3974
|
|
3760
3975
|
def get_text_editor_widget(self, event: object = None) -> tk.Text | None:
|
3761
3976
|
try:
|
3762
|
-
return self.MT.text_editor.
|
3977
|
+
return self.MT.text_editor.tktext
|
3763
3978
|
except Exception:
|
3764
3979
|
return None
|
3765
3980
|
|
@@ -3771,7 +3986,7 @@ class Sheet(tk.Frame):
|
|
3771
3986
|
if key == "all":
|
3772
3987
|
for key in self.MT.text_editor_user_bound_keys:
|
3773
3988
|
try:
|
3774
|
-
self.MT.text_editor.
|
3989
|
+
self.MT.text_editor.tktext.unbind(key)
|
3775
3990
|
except Exception:
|
3776
3991
|
pass
|
3777
3992
|
self.MT.text_editor_user_bound_keys = {}
|
@@ -3779,11 +3994,20 @@ class Sheet(tk.Frame):
|
|
3779
3994
|
if key in self.MT.text_editor_user_bound_keys:
|
3780
3995
|
del self.MT.text_editor_user_bound_keys[key]
|
3781
3996
|
try:
|
3782
|
-
self.MT.text_editor.
|
3997
|
+
self.MT.text_editor.tktext.unbind(key)
|
3783
3998
|
except Exception:
|
3784
3999
|
pass
|
3785
4000
|
return self
|
3786
4001
|
|
4002
|
+
def get_text_editor_value(self) -> str | None:
|
4003
|
+
return self.MT.text_editor.get()
|
4004
|
+
|
4005
|
+
def close_text_editor(self, set_data: bool = True) -> Sheet:
|
4006
|
+
if self.MT.text_editor.open:
|
4007
|
+
event = ("ButtonPress-1",) if set_data else ("Escape",)
|
4008
|
+
self.MT.close_text_editor(editor_info=self.MT.text_editor.coords + event)
|
4009
|
+
return self
|
4010
|
+
|
3787
4011
|
# Sheet Options and Other Functions
|
3788
4012
|
|
3789
4013
|
def set_options(self, redraw: bool = True, **kwargs) -> Sheet:
|
@@ -3797,29 +4021,7 @@ class Sheet(tk.Frame):
|
|
3797
4021
|
else "".join(self.ops.from_clipboard_delimiters)
|
3798
4022
|
)
|
3799
4023
|
if "default_row_height" in kwargs:
|
3800
|
-
self.
|
3801
|
-
kwargs["default_row_height"] if isinstance(kwargs["default_row_height"], str) else "pixels",
|
3802
|
-
(
|
3803
|
-
kwargs["default_row_height"]
|
3804
|
-
if isinstance(kwargs["default_row_height"], int)
|
3805
|
-
else self.MT.get_lines_cell_height(int(kwargs["default_row_height"]))
|
3806
|
-
),
|
3807
|
-
)
|
3808
|
-
if "default_column_width" in kwargs:
|
3809
|
-
self.MT.default_column_width = (
|
3810
|
-
self.MT.min_column_width + 20
|
3811
|
-
if kwargs["column_width"] < self.MT.min_column_width
|
3812
|
-
else int(kwargs["column_width"])
|
3813
|
-
)
|
3814
|
-
if "default_header_height" in kwargs:
|
3815
|
-
self.MT.default_header_height = (
|
3816
|
-
kwargs["default_header_height"] if isinstance(kwargs["default_header_height"], str) else "pixels",
|
3817
|
-
(
|
3818
|
-
kwargs["default_header_height"]
|
3819
|
-
if isinstance(kwargs["default_header_height"], int)
|
3820
|
-
else self.MT.get_lines_cell_height(int(kwargs["default_header_height"]), font=self.ops.header_font)
|
3821
|
-
),
|
3822
|
-
)
|
4024
|
+
self.default_row_height(kwargs["default_row_height"])
|
3823
4025
|
if "default_header" in kwargs:
|
3824
4026
|
self.CH.default_header = kwargs["default_header"].lower()
|
3825
4027
|
if "default_row_index" in kwargs:
|
@@ -3863,11 +4065,44 @@ class Sheet(tk.Frame):
|
|
3863
4065
|
highlightbackground=kwargs["outline_color"],
|
3864
4066
|
highlightcolor=kwargs["outline_color"],
|
3865
4067
|
)
|
4068
|
+
if any(k in kwargs for k in scrollbar_options_keys):
|
4069
|
+
self.set_scrollbar_options()
|
3866
4070
|
self.MT.create_rc_menus()
|
3867
4071
|
self.MT.key_bindings()
|
3868
4072
|
self.set_refresh_timer(redraw)
|
3869
4073
|
return self
|
3870
4074
|
|
4075
|
+
def set_scrollbar_options(self) -> Sheet:
|
4076
|
+
style = ttk.Style()
|
4077
|
+
for orientation in ("vertical", "horizontal"):
|
4078
|
+
style.configure(
|
4079
|
+
f"Sheet{self.unique_id}.{orientation.capitalize()}.TScrollbar",
|
4080
|
+
background=self.ops[f"{orientation}_scroll_background"],
|
4081
|
+
troughcolor=self.ops[f"{orientation}_scroll_troughcolor"],
|
4082
|
+
lightcolor=self.ops[f"{orientation}_scroll_lightcolor"],
|
4083
|
+
darkcolor=self.ops[f"{orientation}_scroll_darkcolor"],
|
4084
|
+
relief=self.ops[f"{orientation}_scroll_relief"],
|
4085
|
+
troughrelief=self.ops[f"{orientation}_scroll_troughrelief"],
|
4086
|
+
bordercolor=self.ops[f"{orientation}_scroll_bordercolor"],
|
4087
|
+
borderwidth=self.ops[f"{orientation}_scroll_borderwidth"],
|
4088
|
+
gripcount=self.ops[f"{orientation}_scroll_gripcount"],
|
4089
|
+
arrowsize=self.ops[f"{orientation}_scroll_arrowsize"],
|
4090
|
+
)
|
4091
|
+
style.map(
|
4092
|
+
f"Sheet{self.unique_id}.{orientation.capitalize()}.TScrollbar",
|
4093
|
+
foreground=[
|
4094
|
+
("!active", self.ops[f"{orientation}_scroll_not_active_fg"]),
|
4095
|
+
("pressed", self.ops[f"{orientation}_scroll_pressed_fg"]),
|
4096
|
+
("active", self.ops[f"{orientation}_scroll_active_fg"]),
|
4097
|
+
],
|
4098
|
+
background=[
|
4099
|
+
("!active", self.ops[f"{orientation}_scroll_not_active_bg"]),
|
4100
|
+
("pressed", self.ops[f"{orientation}_scroll_pressed_bg"]),
|
4101
|
+
("active", self.ops[f"{orientation}_scroll_active_bg"]),
|
4102
|
+
],
|
4103
|
+
)
|
4104
|
+
return self
|
4105
|
+
|
3871
4106
|
def get_cell_options(
|
3872
4107
|
self,
|
3873
4108
|
key: None | str = None,
|
@@ -3968,6 +4203,570 @@ class Sheet(tk.Frame):
|
|
3968
4203
|
self.MT.main_table_redraw_grid_and_text(redraw_header=redraw_header, redraw_row_index=redraw_row_index)
|
3969
4204
|
return self
|
3970
4205
|
|
4206
|
+
# Tags
|
4207
|
+
|
4208
|
+
def tag(
|
4209
|
+
self,
|
4210
|
+
*key: CreateSpanTypes,
|
4211
|
+
tags: Iterator[str] | str = "",
|
4212
|
+
) -> Sheet:
|
4213
|
+
span = self.span_from_key(*key)
|
4214
|
+
rows, cols = self.ranges_from_span(span)
|
4215
|
+
if isinstance(tags, str):
|
4216
|
+
tags = (tags,)
|
4217
|
+
if span.kind == "cell":
|
4218
|
+
for tag in tags:
|
4219
|
+
if tag not in self.MT.tagged_cells:
|
4220
|
+
self.MT.tagged_cells[tag] = set()
|
4221
|
+
for r in rows:
|
4222
|
+
for c in cols:
|
4223
|
+
self.MT.tagged_cells[tag].add((r, c))
|
4224
|
+
elif span.kind == "row":
|
4225
|
+
for tag in tags:
|
4226
|
+
if tag not in self.MT.tagged_rows:
|
4227
|
+
self.MT.tagged_rows[tag] = set()
|
4228
|
+
self.MT.tagged_rows[tag].update(set(rows))
|
4229
|
+
elif span.kind == "column":
|
4230
|
+
for tag in tags:
|
4231
|
+
if tag not in self.MT.tagged_columns:
|
4232
|
+
self.MT.tagged_columns[tag] = set()
|
4233
|
+
self.MT.tagged_columns[tag].update(set(cols))
|
4234
|
+
return self
|
4235
|
+
|
4236
|
+
def tag_cell(
|
4237
|
+
self,
|
4238
|
+
cell: tuple[int, int],
|
4239
|
+
*tags,
|
4240
|
+
) -> Sheet:
|
4241
|
+
if (
|
4242
|
+
not isinstance(cell, tuple)
|
4243
|
+
or not len(cell) == 2
|
4244
|
+
or not isinstance(cell[0], int)
|
4245
|
+
or not isinstance(cell[1], int)
|
4246
|
+
):
|
4247
|
+
raise ValueError("'cell' argument must be tuple[int, int].")
|
4248
|
+
for tag in unpack(tags):
|
4249
|
+
if tag not in self.MT.tagged_cells:
|
4250
|
+
self.MT.tagged_cells[tag] = set()
|
4251
|
+
self.MT.tagged_cells[tag].add(cell)
|
4252
|
+
return self
|
4253
|
+
|
4254
|
+
def tag_rows(
|
4255
|
+
self,
|
4256
|
+
rows: int | Iterator[int],
|
4257
|
+
*tags,
|
4258
|
+
) -> Sheet:
|
4259
|
+
if isinstance(rows, int):
|
4260
|
+
rows = [rows]
|
4261
|
+
for tag in unpack(tags):
|
4262
|
+
if tag not in self.MT.tagged_rows:
|
4263
|
+
self.MT.tagged_rows[tag] = set()
|
4264
|
+
self.MT.tagged_rows[tag].update(rows)
|
4265
|
+
return self
|
4266
|
+
|
4267
|
+
def tag_columns(
|
4268
|
+
self,
|
4269
|
+
columns: int | Iterator[int],
|
4270
|
+
*tags,
|
4271
|
+
) -> Sheet:
|
4272
|
+
if isinstance(columns, int):
|
4273
|
+
columns = [columns]
|
4274
|
+
for tag in unpack(tags):
|
4275
|
+
if tag not in self.MT.tagged_columns:
|
4276
|
+
self.MT.tagged_columns[tag] = set()
|
4277
|
+
self.MT.tagged_columns[tag].update(columns)
|
4278
|
+
return self
|
4279
|
+
|
4280
|
+
def untag(
|
4281
|
+
self,
|
4282
|
+
cell: tuple[int, int] | None = None,
|
4283
|
+
rows: int | Iterator[int] | None = None,
|
4284
|
+
columns: int | Iterator[int] | None = None,
|
4285
|
+
) -> Sheet:
|
4286
|
+
if isinstance(cell, tuple):
|
4287
|
+
for tagged in self.MT.tagged_cells.values():
|
4288
|
+
tagged.discard(cell)
|
4289
|
+
if isinstance(rows, int):
|
4290
|
+
rows = (rows,)
|
4291
|
+
if is_iterable(rows):
|
4292
|
+
for tagged in self.MT.tagged_rows.values():
|
4293
|
+
for row in rows:
|
4294
|
+
tagged.discard(row)
|
4295
|
+
if isinstance(columns, int):
|
4296
|
+
columns = (columns,)
|
4297
|
+
if is_iterable(columns):
|
4298
|
+
for tagged in self.MT.tagged_columns.values():
|
4299
|
+
for column in columns:
|
4300
|
+
tagged.discard(column)
|
4301
|
+
return self
|
4302
|
+
|
4303
|
+
def tag_del(
|
4304
|
+
self,
|
4305
|
+
*tags,
|
4306
|
+
cells: bool = True,
|
4307
|
+
rows: bool = True,
|
4308
|
+
columns: bool = True,
|
4309
|
+
) -> Sheet:
|
4310
|
+
for tag in unpack(tags):
|
4311
|
+
if cells and tag in self.MT.tagged_cells:
|
4312
|
+
del self.MT.tagged_cells[tag]
|
4313
|
+
if rows and tag in self.MT.tagged_rows:
|
4314
|
+
del self.MT.tagged_rows[tag]
|
4315
|
+
if columns and tag in self.MT.tagged_columns:
|
4316
|
+
del self.MT.tagged_columns[tag]
|
4317
|
+
return self
|
4318
|
+
|
4319
|
+
def tag_has(
|
4320
|
+
self,
|
4321
|
+
*tags,
|
4322
|
+
) -> DotDict:
|
4323
|
+
res = DotDict(
|
4324
|
+
cells=set(),
|
4325
|
+
rows=set(),
|
4326
|
+
columns=set(),
|
4327
|
+
)
|
4328
|
+
for tag in unpack(tags):
|
4329
|
+
res.cells.update(self.MT.tagged_cells[tag] if tag in self.MT.tagged_cells else set())
|
4330
|
+
res.rows.update(self.MT.tagged_rows[tag] if tag in self.MT.tagged_rows else set())
|
4331
|
+
res.columns.update(self.MT.tagged_columns[tag] if tag in self.MT.tagged_columns else set())
|
4332
|
+
return res
|
4333
|
+
|
4334
|
+
# Treeview Mode
|
4335
|
+
|
4336
|
+
def tree_build(
|
4337
|
+
self,
|
4338
|
+
data: list[list[object]],
|
4339
|
+
iid_column: int,
|
4340
|
+
parent_column: int,
|
4341
|
+
) -> Sheet:
|
4342
|
+
tally_of_ids = defaultdict(lambda: -1)
|
4343
|
+
ncols = max(map(len, data), default=0)
|
4344
|
+
for rn, row in enumerate(data):
|
4345
|
+
if ncols > (lnr := len(row)):
|
4346
|
+
row += self.MT.get_empty_row_seq(rn, end=ncols, start=lnr)
|
4347
|
+
iid, pid = row[iid_column].lower(), row[parent_column].lower()
|
4348
|
+
if not iid:
|
4349
|
+
continue
|
4350
|
+
tally_of_ids[iid] += 1
|
4351
|
+
if tally_of_ids[iid] > 0:
|
4352
|
+
x = 1
|
4353
|
+
while iid in tally_of_ids:
|
4354
|
+
new = f"{row[iid_column]}_DUPLICATED_{x}"
|
4355
|
+
iid = new.lower()
|
4356
|
+
x += 1
|
4357
|
+
tally_of_ids[iid] += 1
|
4358
|
+
row[iid_column] = new
|
4359
|
+
if iid not in self.RI.tree:
|
4360
|
+
self.RI.tree[iid] = Node(row[iid_column], iid, "")
|
4361
|
+
if iid == pid or self.RI.pid_causes_recursive_loop(iid, pid):
|
4362
|
+
row[parent_column] = ""
|
4363
|
+
pid = ""
|
4364
|
+
if pid:
|
4365
|
+
if pid not in self.RI.tree:
|
4366
|
+
self.RI.tree[pid] = Node(row[parent_column], pid)
|
4367
|
+
self.RI.tree[iid].parent = self.RI.tree[pid]
|
4368
|
+
self.RI.tree[pid].children.append(self.RI.tree[iid])
|
4369
|
+
else:
|
4370
|
+
self.RI.tree[iid].parent = ""
|
4371
|
+
self.RI.tree_rns[iid] = rn
|
4372
|
+
for n in self.RI.tree.values():
|
4373
|
+
if n.parent is None:
|
4374
|
+
n.parent = ""
|
4375
|
+
newrow = self.MT.get_empty_row_seq(len(data), ncols)
|
4376
|
+
newrow[iid_column] = n.text
|
4377
|
+
self.RI.tree_rns[n.iid] = len(data)
|
4378
|
+
data.append(newrow)
|
4379
|
+
self.insert_rows(
|
4380
|
+
idx=0,
|
4381
|
+
rows=[[self.RI.tree[iid]] + data[self.RI.tree_rns[iid]] for iid in self.get_children()],
|
4382
|
+
row_index=True,
|
4383
|
+
create_selections=False,
|
4384
|
+
fill=False,
|
4385
|
+
)
|
4386
|
+
self.RI.tree_rns = {n.iid: i for i, n in enumerate(self.MT._row_index)}
|
4387
|
+
self.hide_rows(
|
4388
|
+
set(self.RI.tree_rns[iid] for iid in self.get_children() if self.RI.tree[iid].parent),
|
4389
|
+
deselect_all=True,
|
4390
|
+
data_indexes=True,
|
4391
|
+
)
|
4392
|
+
return self
|
4393
|
+
|
4394
|
+
def insert(
|
4395
|
+
self,
|
4396
|
+
parent: str = "",
|
4397
|
+
index: None | int | Literal["end"] = None,
|
4398
|
+
iid: None | str = None,
|
4399
|
+
text: None | str = None,
|
4400
|
+
values: None | list = None,
|
4401
|
+
create_selections: bool = False,
|
4402
|
+
) -> str:
|
4403
|
+
if iid is None:
|
4404
|
+
i = 0
|
4405
|
+
while (iid := f"{i}") in self.RI.tree:
|
4406
|
+
i += 1
|
4407
|
+
iid, pid = iid.lower(), parent.lower()
|
4408
|
+
if not iid:
|
4409
|
+
raise ValueError("iid cannot be empty string.")
|
4410
|
+
if iid in self.RI.tree:
|
4411
|
+
raise ValueError(f"iid '{iid}' already exists.")
|
4412
|
+
if iid == pid:
|
4413
|
+
raise ValueError(f"iid '{iid}' cannot be equal to parent '{pid}'.")
|
4414
|
+
if pid and pid not in self.RI.tree:
|
4415
|
+
raise ValueError(f"parent '{parent}' does not exist.")
|
4416
|
+
if text is None:
|
4417
|
+
text = iid
|
4418
|
+
parent_node = self.RI.tree[pid] if parent else ""
|
4419
|
+
self.RI.tree[iid] = Node(text, iid, parent_node)
|
4420
|
+
if self.RI.pid_causes_recursive_loop(iid, pid):
|
4421
|
+
del self.RI.tree[iid]
|
4422
|
+
raise ValueError(f"iid '{iid}' causes a recursive loop with parent '{parent}'.")
|
4423
|
+
if parent_node:
|
4424
|
+
if isinstance(index, int):
|
4425
|
+
idx = self.RI.tree_rns[pid] + index + 1
|
4426
|
+
for count, cid in enumerate(self.get_children(pid)):
|
4427
|
+
if count >= index:
|
4428
|
+
break
|
4429
|
+
idx += sum(1 for _ in self.RI.get_iid_descendants(cid))
|
4430
|
+
self.RI.tree[pid].children.insert(index, self.RI.tree[iid])
|
4431
|
+
else:
|
4432
|
+
idx = self.RI.tree_rns[pid] + sum(1 for _ in self.RI.get_iid_descendants(pid)) + 1
|
4433
|
+
self.RI.tree[pid].children.append(self.RI.tree[iid])
|
4434
|
+
else:
|
4435
|
+
if isinstance(index, int):
|
4436
|
+
idx = index
|
4437
|
+
if index:
|
4438
|
+
for count, cid in enumerate(self.get_children("")):
|
4439
|
+
if count >= index:
|
4440
|
+
break
|
4441
|
+
idx += sum(1 for _ in self.RI.get_iid_descendants(cid)) + 1
|
4442
|
+
else:
|
4443
|
+
idx = len(self.MT._row_index)
|
4444
|
+
self.insert_rows(
|
4445
|
+
idx=idx,
|
4446
|
+
rows=[[self.RI.tree[iid]] + [] if values is None else values],
|
4447
|
+
row_index=True,
|
4448
|
+
create_selections=create_selections,
|
4449
|
+
fill=False,
|
4450
|
+
)
|
4451
|
+
self.RI.tree_rns[iid] = idx
|
4452
|
+
if pid and (pid not in self.RI.tree_open_ids or not self.item_displayed(pid)):
|
4453
|
+
self.hide_rows(idx, deselect_all=False, data_indexes=True)
|
4454
|
+
return iid
|
4455
|
+
|
4456
|
+
def item(
|
4457
|
+
self,
|
4458
|
+
item: str,
|
4459
|
+
iid: str | None = None,
|
4460
|
+
text: str | None = None,
|
4461
|
+
values: list | None = None,
|
4462
|
+
open_: bool | None = None,
|
4463
|
+
) -> DotDict:
|
4464
|
+
if not (item := item.lower()) or item not in self.RI.tree:
|
4465
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4466
|
+
if isinstance(iid, str):
|
4467
|
+
if not (iid := iid.lower()):
|
4468
|
+
raise ValueError(f"iid '{iid}' does not exist.")
|
4469
|
+
if iid in self.RI.tree:
|
4470
|
+
raise ValueError(f"Cannot rename '{iid}', it already exists.")
|
4471
|
+
iid = iid.lower()
|
4472
|
+
self.RI.tree[item].iid = iid
|
4473
|
+
self.RI.tree[iid] = self.RI.tree.pop(item)
|
4474
|
+
self.RI.tree_rns[iid] = self.RI.tree_rns.pop(item)
|
4475
|
+
if iid in self.RI.tree_open_ids:
|
4476
|
+
self.RI.tree_open_ids[iid] = self.RI.tree_open_ids.pop(item)
|
4477
|
+
if isinstance(text, str):
|
4478
|
+
self.RI.tree[item].text = text
|
4479
|
+
if isinstance(values, list):
|
4480
|
+
self.set_data(self.RI.tree_rns[item], values)
|
4481
|
+
if isinstance(open_, bool):
|
4482
|
+
if not self.RI.tree[item].children or not open_:
|
4483
|
+
self.RI.tree_open_ids.discard(item)
|
4484
|
+
if open_:
|
4485
|
+
self.RI.tree_open_ids.add(item)
|
4486
|
+
self.show_rows(
|
4487
|
+
(self.RI.tree_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True)),
|
4488
|
+
redraw=False,
|
4489
|
+
deselect_all=False,
|
4490
|
+
)
|
4491
|
+
elif self.RI.tree[item].children:
|
4492
|
+
self.hide_rows(
|
4493
|
+
(self.RI.tree_rns[did] for did in self.RI.get_iid_descendants(item)),
|
4494
|
+
redraw=False,
|
4495
|
+
deselect_all=False,
|
4496
|
+
data_indexes=True,
|
4497
|
+
)
|
4498
|
+
self.set_refresh_timer(isinstance(text, str) or isinstance(values, list) or isinstance(open_, bool))
|
4499
|
+
return DotDict(
|
4500
|
+
text=self.RI.tree[item].text,
|
4501
|
+
values=self[self.RI.tree_rns[item]].options(ndim=1).data,
|
4502
|
+
open_=item in self.RI.tree_open_ids,
|
4503
|
+
)
|
4504
|
+
|
4505
|
+
def itemrow(self, item: str) -> int:
|
4506
|
+
return self.RI.tree_rns[item.lower()]
|
4507
|
+
|
4508
|
+
def rowitem(self, row: int) -> str | None:
|
4509
|
+
if len(self.MT._row_index) > row:
|
4510
|
+
return self.MT._row_index[row].iid
|
4511
|
+
return None
|
4512
|
+
|
4513
|
+
def get_children(self, item: None | str = None) -> Generator[str]:
|
4514
|
+
if item is None:
|
4515
|
+
for n in self.RI.tree.values():
|
4516
|
+
if not n.parent:
|
4517
|
+
yield n.iid
|
4518
|
+
for iid in self.RI.get_iid_descendants(n.iid):
|
4519
|
+
yield iid
|
4520
|
+
elif item == "":
|
4521
|
+
yield from (n.iid for n in self.RI.tree.values() if not n.parent)
|
4522
|
+
else:
|
4523
|
+
yield from (n.iid for n in self.RI.tree[item].children)
|
4524
|
+
|
4525
|
+
def reset_tree(self) -> Sheet:
|
4526
|
+
self.deselect()
|
4527
|
+
self.RI.reset_tree()
|
4528
|
+
return self
|
4529
|
+
|
4530
|
+
def del_items(self, *items) -> Sheet:
|
4531
|
+
"""
|
4532
|
+
Also deletes all descendants of items
|
4533
|
+
"""
|
4534
|
+
rows_to_del = []
|
4535
|
+
iids_to_del = []
|
4536
|
+
for item in unpack(items):
|
4537
|
+
item = item.lower()
|
4538
|
+
if item not in self.RI.tree:
|
4539
|
+
continue
|
4540
|
+
rows_to_del.append(self.RI.tree_rns[item])
|
4541
|
+
iids_to_del.append(item)
|
4542
|
+
for did in self.RI.get_iid_descendants(item):
|
4543
|
+
rows_to_del.append(self.RI.tree_rns[did])
|
4544
|
+
iids_to_del.append(did)
|
4545
|
+
for item in unpack(items):
|
4546
|
+
self.RI.remove_node_from_parents_children(self.RI.tree[item])
|
4547
|
+
self.del_rows(rows_to_del)
|
4548
|
+
for iid in iids_to_del:
|
4549
|
+
self.RI.tree_open_ids.discard(iid)
|
4550
|
+
if self.RI.tree[iid].parent and len(self.RI.tree[iid].parent.children) == 1:
|
4551
|
+
self.RI.tree_open_ids.discard(self.RI.tree[iid].parent.iid)
|
4552
|
+
del self.RI.tree[iid]
|
4553
|
+
self.set_refresh_timer(True)
|
4554
|
+
return self
|
4555
|
+
|
4556
|
+
def set_children(self, item: str, *newchildren) -> Sheet:
|
4557
|
+
"""
|
4558
|
+
Moves everything in '*newchildren' under 'item'
|
4559
|
+
"""
|
4560
|
+
if (item := item.lower()) and item not in self.RI.tree:
|
4561
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4562
|
+
mapping = {}
|
4563
|
+
to_show = []
|
4564
|
+
if item:
|
4565
|
+
new_parent = self.RI.tree[item]
|
4566
|
+
if new_parent.children:
|
4567
|
+
ctr = self.RI.tree_rns[new_parent.children[-1].iid] + 1
|
4568
|
+
else:
|
4569
|
+
ctr = self.RI.tree_rns[new_parent.iid] + 1
|
4570
|
+
for cid in unpack(newchildren):
|
4571
|
+
if self.RI.pid_causes_recursive_loop(cid, item):
|
4572
|
+
raise ValueError(f"iid '{cid}' causes a recursive loop with parent '{item}'.")
|
4573
|
+
cid_node = self.RI.tree[cid]
|
4574
|
+
mapping[self.RI.tree_rns[cid]] = ctr
|
4575
|
+
if item in self.RI.tree_open_ids and self.item_displayed(item):
|
4576
|
+
to_show.append(ctr)
|
4577
|
+
ctr += 1
|
4578
|
+
for did in self.RI.get_iid_descendants(cid):
|
4579
|
+
mapping[self.RI.tree_rns[did]] = ctr
|
4580
|
+
if to_show and self.RI.ancestors_all_open(did, self.RI.tree[cid].parent):
|
4581
|
+
to_show.append(ctr)
|
4582
|
+
ctr += 1
|
4583
|
+
self.RI.remove_node_from_parents_children(cid_node)
|
4584
|
+
cid_node.parent = new_parent
|
4585
|
+
new_parent.children.append(cid_node)
|
4586
|
+
else:
|
4587
|
+
ctr = (
|
4588
|
+
len(self.MT._row_index)
|
4589
|
+
- len(newchildren)
|
4590
|
+
- sum(1 for cid in unpack(newchildren) for _ in self.RI.get_iid_descendants(cid))
|
4591
|
+
)
|
4592
|
+
for cid in unpack(newchildren):
|
4593
|
+
cid_node = self.RI.tree[cid]
|
4594
|
+
mapping[self.RI.tree_rns[cid]] = ctr
|
4595
|
+
to_show.append(ctr)
|
4596
|
+
ctr += 1
|
4597
|
+
for did in self.RI.get_iid_descendants(cid):
|
4598
|
+
mapping[self.RI.tree_rns[did]] = ctr
|
4599
|
+
if self.RI.ancestors_all_open(did, cid_node.parent):
|
4600
|
+
to_show.append(ctr)
|
4601
|
+
ctr += 1
|
4602
|
+
self.RI.remove_node_from_parents_children(cid_node)
|
4603
|
+
self.RI.tree[cid].parent = ""
|
4604
|
+
self.mapping_move_rows(
|
4605
|
+
data_new_idxs=mapping,
|
4606
|
+
data_indexes=True,
|
4607
|
+
create_selections=False,
|
4608
|
+
redraw=False,
|
4609
|
+
)
|
4610
|
+
if item and (item not in self.RI.tree_open_ids or not self.item_displayed(item)):
|
4611
|
+
self.hide_rows(set(mapping.values()), data_indexes=True)
|
4612
|
+
self.show_rows(to_show)
|
4613
|
+
self.set_refresh_timer(True)
|
4614
|
+
return self
|
4615
|
+
|
4616
|
+
def move(self, item: str, parent: str, index: int = 0) -> Sheet:
|
4617
|
+
"""
|
4618
|
+
Moves item to be under parent as child at index
|
4619
|
+
'parent' can be empty string which will make item a top node
|
4620
|
+
"""
|
4621
|
+
if (item := item.lower()) and item not in self.RI.tree:
|
4622
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4623
|
+
if (parent := parent.lower()) and parent not in self.RI.tree:
|
4624
|
+
raise ValueError(f"Parent '{parent}' does not exist.")
|
4625
|
+
mapping = {}
|
4626
|
+
to_show = []
|
4627
|
+
item_node = self.RI.tree[item]
|
4628
|
+
if parent:
|
4629
|
+
if self.RI.pid_causes_recursive_loop(item, parent):
|
4630
|
+
raise ValueError(f"iid '{item}' causes a recursive loop with parent '{parent}'.")
|
4631
|
+
parent_node = self.RI.tree[parent]
|
4632
|
+
if parent_node.children:
|
4633
|
+
if len(parent_node.children) < index:
|
4634
|
+
index = len(parent_node.children)
|
4635
|
+
ctr = self.RI.tree_rns[parent_node.children[index].iid]
|
4636
|
+
else:
|
4637
|
+
ctr = self.RI.tree_rns[parent_node.iid] + 1
|
4638
|
+
mapping[self.RI.tree_rns[item]] = ctr
|
4639
|
+
if parent in self.RI.tree_open_ids and self.item_displayed(parent):
|
4640
|
+
to_show.append(ctr)
|
4641
|
+
ctr += 1
|
4642
|
+
for did in self.RI.get_iid_descendants(item):
|
4643
|
+
mapping[self.RI.tree_rns[did]] = ctr
|
4644
|
+
if to_show and self.RI.ancestors_all_open(did, item_node.parent):
|
4645
|
+
to_show.append(ctr)
|
4646
|
+
ctr += 1
|
4647
|
+
self.RI.remove_node_from_parents_children(item_node)
|
4648
|
+
item_node.parent = parent_node
|
4649
|
+
parent_node.children.append(item_node)
|
4650
|
+
else:
|
4651
|
+
if len(self.MT._row_index) < index:
|
4652
|
+
index = len(self.MT._row_index)
|
4653
|
+
ctr = index
|
4654
|
+
mapping[self.RI.tree_rns[item]] = ctr
|
4655
|
+
to_show.append(ctr)
|
4656
|
+
ctr += 1
|
4657
|
+
for did in self.RI.get_iid_descendants(item):
|
4658
|
+
mapping[self.RI.tree_rns[did]] = ctr
|
4659
|
+
if to_show and self.RI.ancestors_all_open(did, item_node.parent):
|
4660
|
+
to_show.append(ctr)
|
4661
|
+
ctr += 1
|
4662
|
+
self.RI.remove_node_from_parents_children(item_node)
|
4663
|
+
self.RI.tree[item].parent = ""
|
4664
|
+
self.mapping_move_rows(
|
4665
|
+
data_new_idxs=mapping,
|
4666
|
+
data_indexes=True,
|
4667
|
+
create_selections=False,
|
4668
|
+
redraw=False,
|
4669
|
+
)
|
4670
|
+
if parent and (parent not in self.RI.tree_open_ids or not self.item_displayed(parent)):
|
4671
|
+
self.hide_rows(set(mapping.values()), data_indexes=True)
|
4672
|
+
self.show_rows(to_show)
|
4673
|
+
self.set_refresh_timer(True)
|
4674
|
+
return self
|
4675
|
+
|
4676
|
+
reattach = move
|
4677
|
+
|
4678
|
+
def exists(self, item: str) -> bool:
|
4679
|
+
return item in self.RI.tree
|
4680
|
+
|
4681
|
+
def parent(self, item: str) -> str:
|
4682
|
+
if (item := item.lower()) not in self.RI.tree:
|
4683
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4684
|
+
return self.RI.tree[item].parent.iid if self.RI.tree[item].parent else self.RI.tree[item].parent
|
4685
|
+
|
4686
|
+
def index(self, item: str) -> int:
|
4687
|
+
if (item := item.lower()) not in self.RI.tree:
|
4688
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4689
|
+
if not self.RI.tree[item].parent:
|
4690
|
+
return sorted(self.RI.tree_rns[iid] for iid in self.get_children("")).index(self.RI.tree_rns[item])
|
4691
|
+
return self.RI.tree[item].parent.children.index(self.RI.tree[item])
|
4692
|
+
|
4693
|
+
def item_displayed(self, item: str) -> bool:
|
4694
|
+
"""
|
4695
|
+
Check if an item (row) is currently displayed on the sheet
|
4696
|
+
- Does not check if the item is visible to the user
|
4697
|
+
"""
|
4698
|
+
if (item := item.lower()) not in self.RI.tree:
|
4699
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4700
|
+
return self.RI.tree_rns[item] in self.MT.displayed_rows
|
4701
|
+
|
4702
|
+
def display_item(self, item: str) -> Sheet:
|
4703
|
+
"""
|
4704
|
+
Ensure that item is displayed in the tree
|
4705
|
+
- Opens all of an item's ancestors
|
4706
|
+
- Unlike the ttk treeview 'see' function
|
4707
|
+
this function does **NOT** scroll to the item
|
4708
|
+
"""
|
4709
|
+
if (item := item.lower()) not in self.RI.tree:
|
4710
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4711
|
+
if self.RI.tree[item].parent:
|
4712
|
+
for iid in self.RI.get_iid_ancestors(item):
|
4713
|
+
self.item(iid, open_=True)
|
4714
|
+
|
4715
|
+
def scroll_to_item(self, item: str) -> Sheet:
|
4716
|
+
"""
|
4717
|
+
Scrolls to an item and ensures that it is displayed
|
4718
|
+
"""
|
4719
|
+
if (item := item.lower()) not in self.RI.tree:
|
4720
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4721
|
+
self.display_item(item)
|
4722
|
+
self.see(row=bisect_left(self.MT.displayed_rows, self.RI.tree_rns[item]), keep_xscroll=True)
|
4723
|
+
|
4724
|
+
def selection(self) -> list[str]:
|
4725
|
+
"""
|
4726
|
+
Get currently selected item ids
|
4727
|
+
- Only includes selected rows
|
4728
|
+
"""
|
4729
|
+
return [self.MT._row_index[self.displayed_row_to_data(rn)].iid for rn in self.get_selected_rows()]
|
4730
|
+
|
4731
|
+
def selection_set(self, *items) -> Sheet:
|
4732
|
+
self.deselect()
|
4733
|
+
self.selection_add(*items)
|
4734
|
+
return self
|
4735
|
+
|
4736
|
+
def selection_add(self, *items) -> Sheet:
|
4737
|
+
for item in unpack(items):
|
4738
|
+
if (item := item.lower()) not in self.RI.tree:
|
4739
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4740
|
+
if not self.item_displayed(item):
|
4741
|
+
self.display_item(item)
|
4742
|
+
self.add_row_selection(bisect_left(self.MT.displayed_rows, self.RI.tree_rns[item]))
|
4743
|
+
return self
|
4744
|
+
|
4745
|
+
def selection_remove(self, *items) -> Sheet:
|
4746
|
+
for item in unpack(items):
|
4747
|
+
if (item := item.lower()) not in self.RI.tree:
|
4748
|
+
raise ValueError(f"Item '{item}' does not exist.")
|
4749
|
+
try:
|
4750
|
+
self.deselect(bisect_left(self.MT.displayed_rows, self.RI.tree_rns[item]))
|
4751
|
+
except Exception:
|
4752
|
+
continue
|
4753
|
+
return self
|
4754
|
+
|
4755
|
+
def selection_toggle(self, *items) -> Sheet:
|
4756
|
+
selected = set(self.MT._row_index[self.displayed_row_to_data(rn)].iid for rn in self.get_selected_rows())
|
4757
|
+
add = []
|
4758
|
+
remove = []
|
4759
|
+
for item in unpack(items):
|
4760
|
+
if (item := item.lower()) not in self.RI.tree:
|
4761
|
+
continue
|
4762
|
+
if item in selected:
|
4763
|
+
remove.append(item)
|
4764
|
+
else:
|
4765
|
+
add.append(item)
|
4766
|
+
self.selection_remove(*remove)
|
4767
|
+
self.selection_add(*add)
|
4768
|
+
return self
|
4769
|
+
|
3971
4770
|
# Functions not in docs
|
3972
4771
|
|
3973
4772
|
def emit_event(
|
@@ -4005,10 +4804,10 @@ class Sheet(tk.Frame):
|
|
4005
4804
|
table, index, header = span.table, span.index, span.header
|
4006
4805
|
# index header
|
4007
4806
|
if header and span.kind in ("cell", "column"):
|
4008
|
-
self.CH.
|
4807
|
+
self.CH.hide_dropdown_window()
|
4009
4808
|
del_from_options(self.CH.cell_options, key, cols)
|
4010
4809
|
if index and span.kind in ("cell", "row"):
|
4011
|
-
self.RI.
|
4810
|
+
self.RI.hide_dropdown_window()
|
4012
4811
|
del_from_options(self.RI.cell_options, key, rows)
|
4013
4812
|
# table
|
4014
4813
|
if table and span.kind == "cell":
|
@@ -4023,7 +4822,7 @@ class Sheet(tk.Frame):
|
|
4023
4822
|
# ########## TABLE ##########
|
4024
4823
|
|
4025
4824
|
def del_cell_options_dropdown(self, datarn: int, datacn: int) -> None:
|
4026
|
-
self.MT.
|
4825
|
+
self.MT.hide_dropdown_window()
|
4027
4826
|
if (datarn, datacn) in self.MT.cell_options and "dropdown" in self.MT.cell_options[(datarn, datacn)]:
|
4028
4827
|
del self.MT.cell_options[(datarn, datacn)]["dropdown"]
|
4029
4828
|
|
@@ -4036,7 +4835,7 @@ class Sheet(tk.Frame):
|
|
4036
4835
|
self.del_cell_options_checkbox(datarn, datacn)
|
4037
4836
|
|
4038
4837
|
def del_row_options_dropdown(self, datarn: int) -> None:
|
4039
|
-
self.MT.
|
4838
|
+
self.MT.hide_dropdown_window()
|
4040
4839
|
if datarn in self.MT.row_options and "dropdown" in self.MT.row_options[datarn]:
|
4041
4840
|
del self.MT.row_options[datarn]["dropdown"]
|
4042
4841
|
|
@@ -4049,7 +4848,7 @@ class Sheet(tk.Frame):
|
|
4049
4848
|
self.del_row_options_checkbox(datarn)
|
4050
4849
|
|
4051
4850
|
def del_column_options_dropdown(self, datacn: int) -> None:
|
4052
|
-
self.MT.
|
4851
|
+
self.MT.hide_dropdown_window()
|
4053
4852
|
if datacn in self.MT.col_options and "dropdown" in self.MT.col_options[datacn]:
|
4054
4853
|
del self.MT.col_options[datacn]["dropdown"]
|
4055
4854
|
|
@@ -4064,7 +4863,7 @@ class Sheet(tk.Frame):
|
|
4064
4863
|
# ########## INDEX ##########
|
4065
4864
|
|
4066
4865
|
def del_index_cell_options_dropdown(self, datarn: int) -> None:
|
4067
|
-
self.RI.
|
4866
|
+
self.RI.hide_dropdown_window()
|
4068
4867
|
if datarn in self.RI.cell_options and "dropdown" in self.RI.cell_options[datarn]:
|
4069
4868
|
del self.RI.cell_options[datarn]["dropdown"]
|
4070
4869
|
|
@@ -4079,7 +4878,7 @@ class Sheet(tk.Frame):
|
|
4079
4878
|
# ########## HEADER ##########
|
4080
4879
|
|
4081
4880
|
def del_header_cell_options_dropdown(self, datacn: int) -> None:
|
4082
|
-
self.CH.
|
4881
|
+
self.CH.hide_dropdown_window()
|
4083
4882
|
if datacn in self.CH.cell_options and "dropdown" in self.CH.cell_options[datacn]:
|
4084
4883
|
del self.CH.cell_options[datacn]["dropdown"]
|
4085
4884
|
|
@@ -4300,7 +5099,7 @@ class Sheet(tk.Frame):
|
|
4300
5099
|
if add_rows:
|
4301
5100
|
maxidx = len(self.MT.data) - 1
|
4302
5101
|
total_cols = None
|
4303
|
-
height = self.MT.
|
5102
|
+
height = self.MT.get_default_row_height()
|
4304
5103
|
for rn, v in enumerate(values):
|
4305
5104
|
if rn > maxidx:
|
4306
5105
|
if total_cols is None:
|
@@ -4412,13 +5211,11 @@ class Sheet(tk.Frame):
|
|
4412
5211
|
|
4413
5212
|
def dehighlight_rows(
|
4414
5213
|
self,
|
4415
|
-
rows: list |
|
5214
|
+
rows: list[int] | Literal["all"] = [],
|
4416
5215
|
redraw: bool = True,
|
4417
5216
|
) -> None:
|
4418
5217
|
if isinstance(rows, int):
|
4419
5218
|
rows = [rows]
|
4420
|
-
else:
|
4421
|
-
rows = rows
|
4422
5219
|
if not rows or rows == "all":
|
4423
5220
|
for r in self.MT.row_options:
|
4424
5221
|
if "highlight" in self.MT.row_options[r]:
|
@@ -4439,11 +5236,13 @@ class Sheet(tk.Frame):
|
|
4439
5236
|
pass
|
4440
5237
|
self.set_refresh_timer(redraw)
|
4441
5238
|
|
4442
|
-
def dehighlight_columns(
|
5239
|
+
def dehighlight_columns(
|
5240
|
+
self,
|
5241
|
+
columns: list[int] | Literal["all"] = [],
|
5242
|
+
redraw: bool = True,
|
5243
|
+
) -> None:
|
4443
5244
|
if isinstance(columns, int):
|
4444
5245
|
columns = [columns]
|
4445
|
-
else:
|
4446
|
-
columns = columns
|
4447
5246
|
if not columns or columns == "all":
|
4448
5247
|
for c in self.MT.col_options:
|
4449
5248
|
if "highlight" in self.MT.col_options[c]:
|
@@ -4466,7 +5265,7 @@ class Sheet(tk.Frame):
|
|
4466
5265
|
|
4467
5266
|
def highlight_rows(
|
4468
5267
|
self,
|
4469
|
-
rows:
|
5268
|
+
rows: Iterator[int] | int,
|
4470
5269
|
bg: None | str = None,
|
4471
5270
|
fg: None | str = None,
|
4472
5271
|
highlight_index: bool = True,
|
@@ -4484,7 +5283,7 @@ class Sheet(tk.Frame):
|
|
4484
5283
|
|
4485
5284
|
def highlight_columns(
|
4486
5285
|
self,
|
4487
|
-
columns:
|
5286
|
+
columns: Iterator[int] | int,
|
4488
5287
|
bg: bool | None | str = False,
|
4489
5288
|
fg: bool | None | str = False,
|
4490
5289
|
highlight_header: bool = True,
|
@@ -4946,26 +5745,17 @@ class Sheet(tk.Frame):
|
|
4946
5745
|
return self
|
4947
5746
|
|
4948
5747
|
def get_checkboxes(self) -> dict:
|
4949
|
-
|
5748
|
+
return {
|
4950
5749
|
**{k: v["checkbox"] for k, v in self.MT.cell_options.items() if "checkbox" in v},
|
4951
5750
|
**{k: v["checkbox"] for k, v in self.MT.row_options.items() if "checkbox" in v},
|
4952
5751
|
**{k: v["checkbox"] for k, v in self.MT.col_options.items() if "checkbox" in v},
|
4953
5752
|
}
|
4954
|
-
if "checkbox" in self.MT.options:
|
4955
|
-
return {**d, "checkbox": self.MT.options["checkbox"]}
|
4956
|
-
return d
|
4957
5753
|
|
4958
5754
|
def get_header_checkboxes(self) -> dict:
|
4959
|
-
|
4960
|
-
if "checkbox" in self.CH.options:
|
4961
|
-
return {**d, "checkbox": self.CH.options["checkbox"]}
|
4962
|
-
return d
|
5755
|
+
return {k: v["checkbox"] for k, v in self.CH.cell_options.items() if "checkbox" in v}
|
4963
5756
|
|
4964
5757
|
def get_index_checkboxes(self) -> dict:
|
4965
|
-
|
4966
|
-
if "checkbox" in self.RI.options:
|
4967
|
-
return {**d, "checkbox": self.RI.options["checkbox"]}
|
4968
|
-
return d
|
5758
|
+
return {k: v["checkbox"] for k, v in self.RI.cell_options.items() if "checkbox" in v}
|
4969
5759
|
|
4970
5760
|
def create_dropdown(
|
4971
5761
|
self,
|
@@ -5212,9 +6002,8 @@ class Sheet(tk.Frame):
|
|
5212
6002
|
set_value: object = None,
|
5213
6003
|
) -> Sheet:
|
5214
6004
|
if set_existing_dropdown:
|
5215
|
-
if self.MT.
|
5216
|
-
r_ = self.MT.
|
5217
|
-
c_ = self.MT.existing_dropdown_window.c
|
6005
|
+
if self.MT.dropdown.open:
|
6006
|
+
r_, c_ = self.MT.dropdown.get_coords()
|
5218
6007
|
else:
|
5219
6008
|
raise Exception("No dropdown box is currently open")
|
5220
6009
|
else:
|
@@ -5222,16 +6011,12 @@ class Sheet(tk.Frame):
|
|
5222
6011
|
c_ = c
|
5223
6012
|
kwargs = self.MT.get_cell_kwargs(r, c, key="dropdown")
|
5224
6013
|
kwargs["values"] = values
|
5225
|
-
if
|
5226
|
-
|
6014
|
+
if self.MT.dropdown.open:
|
6015
|
+
self.MT.dropdown.window.values(values)
|
5227
6016
|
if set_value is not None:
|
5228
6017
|
self.set_cell_data(r_, c_, set_value)
|
5229
|
-
if
|
5230
|
-
|
5231
|
-
and self.MT.text_editor_loc is not None
|
5232
|
-
and self.MT.text_editor is not None
|
5233
|
-
):
|
5234
|
-
self.MT.text_editor.set_text(set_value)
|
6018
|
+
if self.MT.dropdown.open:
|
6019
|
+
self.MT.text_editor.window.set_text(set_value)
|
5235
6020
|
return self
|
5236
6021
|
|
5237
6022
|
def set_header_dropdown_values(
|
@@ -5242,8 +6027,8 @@ class Sheet(tk.Frame):
|
|
5242
6027
|
set_value: object = None,
|
5243
6028
|
) -> Sheet:
|
5244
6029
|
if set_existing_dropdown:
|
5245
|
-
if self.CH.
|
5246
|
-
c_ = self.CH.
|
6030
|
+
if self.CH.dropdown.open:
|
6031
|
+
c_ = self.CH.dropdown.get_coords()
|
5247
6032
|
else:
|
5248
6033
|
raise Exception("No dropdown box is currently open")
|
5249
6034
|
else:
|
@@ -5251,10 +6036,11 @@ class Sheet(tk.Frame):
|
|
5251
6036
|
kwargs = self.CH.get_cell_kwargs(c_, key="dropdown")
|
5252
6037
|
if kwargs:
|
5253
6038
|
kwargs["values"] = values
|
5254
|
-
if
|
5255
|
-
|
6039
|
+
if self.CH.dropdown.open:
|
6040
|
+
self.CH.dropdown.window.values(values)
|
5256
6041
|
if set_value is not None:
|
5257
6042
|
self.MT.headers(newheaders=set_value, index=c_)
|
6043
|
+
|
5258
6044
|
return self
|
5259
6045
|
|
5260
6046
|
def set_index_dropdown_values(
|
@@ -5265,8 +6051,8 @@ class Sheet(tk.Frame):
|
|
5265
6051
|
set_value: object = None,
|
5266
6052
|
) -> Sheet:
|
5267
6053
|
if set_existing_dropdown:
|
5268
|
-
if self.RI.
|
5269
|
-
r_ = self.RI.
|
6054
|
+
if self.RI.current_dropdown_window is not None:
|
6055
|
+
r_ = self.RI.current_dropdown_window.r
|
5270
6056
|
else:
|
5271
6057
|
raise Exception("No dropdown box is currently open")
|
5272
6058
|
else:
|
@@ -5274,10 +6060,11 @@ class Sheet(tk.Frame):
|
|
5274
6060
|
kwargs = self.RI.get_cell_kwargs(r_, key="dropdown")
|
5275
6061
|
if kwargs:
|
5276
6062
|
kwargs["values"] = values
|
5277
|
-
if
|
5278
|
-
|
6063
|
+
if self.RI.current_dropdown_window is not None:
|
6064
|
+
self.RI.current_dropdown_window.values(values)
|
5279
6065
|
if set_value is not None:
|
5280
6066
|
self.MT.row_index(newindex=set_value, index=r_)
|
6067
|
+
# here
|
5281
6068
|
return self
|
5282
6069
|
|
5283
6070
|
def get_dropdown_values(self, r: int = 0, c: int = 0) -> None | list:
|
@@ -5491,7 +6278,7 @@ class Dropdown(Sheet):
|
|
5491
6278
|
parent: tk.Misc,
|
5492
6279
|
r: int,
|
5493
6280
|
c: int,
|
5494
|
-
|
6281
|
+
ops: dict,
|
5495
6282
|
outline_color: str,
|
5496
6283
|
width: int | None = None,
|
5497
6284
|
height: int | None = None,
|
@@ -5503,7 +6290,9 @@ class Dropdown(Sheet):
|
|
5503
6290
|
arrowkey_RIGHT: Callable | None = None,
|
5504
6291
|
arrowkey_LEFT: Callable | None = None,
|
5505
6292
|
align: str = "w",
|
5506
|
-
# False for using r, c
|
6293
|
+
# False for using r, c
|
6294
|
+
# "r" for r
|
6295
|
+
# "c" for c
|
5507
6296
|
single_index: str | bool = False,
|
5508
6297
|
) -> None:
|
5509
6298
|
Sheet.__init__(
|
@@ -5511,7 +6300,7 @@ class Dropdown(Sheet):
|
|
5511
6300
|
parent=parent,
|
5512
6301
|
outline_thickness=outline_thickness,
|
5513
6302
|
outline_color=outline_color,
|
5514
|
-
table_grid_fg=
|
6303
|
+
table_grid_fg=ops.popup_menu_fg,
|
5515
6304
|
show_horizontal_grid=True,
|
5516
6305
|
show_vertical_grid=False,
|
5517
6306
|
show_header=False,
|
@@ -5525,24 +6314,23 @@ class Dropdown(Sheet):
|
|
5525
6314
|
horizontal_grid_to_end_of_window=True,
|
5526
6315
|
set_cell_sizes_on_zoom=True,
|
5527
6316
|
show_selected_cells_border=False,
|
5528
|
-
table_selected_cells_border_fg=
|
5529
|
-
table_selected_cells_bg=
|
5530
|
-
table_selected_rows_border_fg=
|
5531
|
-
table_selected_rows_bg=
|
5532
|
-
table_selected_rows_fg=
|
6317
|
+
table_selected_cells_border_fg=ops.popup_menu_fg,
|
6318
|
+
table_selected_cells_bg=ops.popup_menu_highlight_bg,
|
6319
|
+
table_selected_rows_border_fg=ops.popup_menu_fg,
|
6320
|
+
table_selected_rows_bg=ops.popup_menu_highlight_bg,
|
6321
|
+
table_selected_rows_fg=ops.popup_menu_highlight_fg,
|
5533
6322
|
width=width,
|
5534
6323
|
height=height,
|
5535
6324
|
font=font if font else self.ops.table_font,
|
5536
|
-
table_fg=
|
5537
|
-
table_bg=
|
6325
|
+
table_fg=ops.popup_menu_fg,
|
6326
|
+
table_bg=ops.popup_menu_bg,
|
6327
|
+
**{k: ops[k] for k in scrollbar_options_keys},
|
5538
6328
|
)
|
5539
6329
|
self.parent = parent
|
5540
6330
|
self.close_dropdown_window = close_dropdown_window
|
5541
6331
|
self.search_function = search_function
|
5542
6332
|
self.arrowkey_RIGHT = arrowkey_RIGHT
|
5543
6333
|
self.arrowkey_LEFT = arrowkey_LEFT
|
5544
|
-
self.h_ = height
|
5545
|
-
self.w_ = width
|
5546
6334
|
self.r = r
|
5547
6335
|
self.c = c
|
5548
6336
|
self.row = -1
|
@@ -5621,6 +6409,13 @@ class Dropdown(Sheet):
|
|
5621
6409
|
else:
|
5622
6410
|
self.close_dropdown_window(self.r, self.c, self.get_cell_data(row, 0))
|
5623
6411
|
|
6412
|
+
def get_coords(self) -> int | tuple[int, int]:
|
6413
|
+
if self.single_index == "r":
|
6414
|
+
return self.r
|
6415
|
+
elif self.single_index == "c":
|
6416
|
+
return self.c
|
6417
|
+
return self.r, self.c
|
6418
|
+
|
5624
6419
|
def values(self, values: list = [], redraw: bool = True) -> None:
|
5625
6420
|
self.set_sheet_data(
|
5626
6421
|
[[v] for v in values],
|