tksheet 7.2.10__tar.gz → 7.2.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {tksheet-7.2.10/tksheet.egg-info → tksheet-7.2.12}/PKG-INFO +1 -1
  2. {tksheet-7.2.10 → tksheet-7.2.12}/pyproject.toml +1 -1
  3. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/__init__.py +1 -1
  4. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/column_headers.py +44 -32
  5. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/functions.py +14 -2
  6. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/main_table.py +36 -14
  7. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/other_classes.py +57 -18
  8. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/row_index.py +50 -53
  9. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/sheet.py +14 -4
  10. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/themes.py +4 -4
  11. {tksheet-7.2.10 → tksheet-7.2.12/tksheet.egg-info}/PKG-INFO +1 -1
  12. {tksheet-7.2.10 → tksheet-7.2.12}/LICENSE.txt +0 -0
  13. {tksheet-7.2.10 → tksheet-7.2.12}/README.md +0 -0
  14. {tksheet-7.2.10 → tksheet-7.2.12}/setup.cfg +0 -0
  15. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/colors.py +0 -0
  16. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/formatters.py +0 -0
  17. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/sheet_options.py +0 -0
  18. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/text_editor.py +0 -0
  19. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/top_left_rectangle.py +0 -0
  20. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/types.py +0 -0
  21. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet/vars.py +0 -0
  22. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet.egg-info/SOURCES.txt +0 -0
  23. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet.egg-info/dependency_links.txt +0 -0
  24. {tksheet-7.2.10 → tksheet-7.2.12}/tksheet.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tksheet
3
- Version: 7.2.10
3
+ Version: 7.2.12
4
4
  Summary: Tkinter table / sheet widget
5
5
  Author-email: ragardner <github@ragardner.simplelogin.com>
6
6
  License: Copyright (c) 2019 ragardner and open source contributors
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
  name = "tksheet"
7
7
  description = "Tkinter table / sheet widget"
8
8
  readme = "README.md"
9
- version = "7.2.10"
9
+ version = "7.2.12"
10
10
  authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
11
11
  requires-python = ">=3.8"
12
12
  license = {file = "LICENSE.txt"}
@@ -4,7 +4,7 @@
4
4
  tksheet - A Python tkinter table widget
5
5
  """
6
6
 
7
- __version__ = "7.2.10"
7
+ __version__ = "7.2.12"
8
8
 
9
9
  from .colors import (
10
10
  color_map,
@@ -481,7 +481,6 @@ class ColumnHeaders(tk.Canvas):
481
481
  if y < self.MT.min_header_height:
482
482
  y = int(self.MT.min_header_height)
483
483
  self.new_col_height = y
484
- self.create_resize_line(x1, y, x2, y, width=1, fill=self.PAR.ops.resizing_line_fg, tag="rhl")
485
484
  elif self.MT.identify_col(x=event.x, allow_end=False) is None:
486
485
  self.MT.deselect("all")
487
486
  elif self.col_selection_enabled and self.rsz_w is None and self.rsz_h is None:
@@ -540,22 +539,21 @@ class ColumnHeaders(tk.Canvas):
540
539
  fill=self.PAR.ops.resizing_line_fg,
541
540
  tag="rwl2",
542
541
  )
542
+ self.drag_width_resize()
543
543
  elif self.height_resizing_enabled and self.rsz_h is not None and self.currently_resizing_height:
544
544
  evy = event.y
545
- self.hide_resize_and_ctrl_lines(ctrl_lines=False)
546
545
  if evy > self.current_height:
547
546
  y = self.MT.canvasy(evy - self.current_height)
548
547
  if evy > self.MT.max_header_height:
549
548
  evy = int(self.MT.max_header_height)
550
549
  y = self.MT.canvasy(evy - self.current_height)
551
550
  self.new_col_height = evy
552
- self.MT.create_resize_line(x1, y, x2, y, width=1, fill=self.PAR.ops.resizing_line_fg, tag="rhl")
553
551
  else:
554
552
  y = evy
555
553
  if y < self.MT.min_header_height:
556
554
  y = int(self.MT.min_header_height)
557
555
  self.new_col_height = y
558
- self.create_resize_line(x1, y, x2, y, width=1, fill=self.PAR.ops.resizing_line_fg, tag="rhl")
556
+ self.drag_height_resize()
559
557
  elif (
560
558
  self.drag_and_drop_enabled
561
559
  and self.col_selection_enabled
@@ -602,6 +600,10 @@ class ColumnHeaders(tk.Canvas):
602
600
  self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=False)
603
601
  try_binding(self.extra_b1_motion_func, event)
604
602
 
603
+ def drag_height_resize(self) -> None:
604
+ self.set_height(self.new_col_height, set_TL=True)
605
+ self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
606
+
605
607
  def get_b1_motion_box(self, start_col: int, end_col: int) -> tuple[int, int, int, int, Literal["columns"]]:
606
608
  if end_col >= start_col:
607
609
  return 0, start_col, len(self.MT.row_positions) - 1, end_col + 1, "columns"
@@ -779,6 +781,32 @@ class ColumnHeaders(tk.Canvas):
779
781
  return True
780
782
  return False
781
783
 
784
+ def drag_width_resize(self) -> None:
785
+ new_col_pos = int(self.coords("rwl")[0])
786
+ old_width = self.MT.col_positions[self.rsz_w] - self.MT.col_positions[self.rsz_w - 1]
787
+ size = new_col_pos - self.MT.col_positions[self.rsz_w - 1]
788
+ if size < self.MT.min_column_width:
789
+ new_col_pos = ceil(self.MT.col_positions[self.rsz_w - 1] + self.MT.min_column_width)
790
+ elif size > self.MT.max_column_width:
791
+ new_col_pos = floor(self.MT.col_positions[self.rsz_w - 1] + self.MT.max_column_width)
792
+ increment = new_col_pos - self.MT.col_positions[self.rsz_w]
793
+ self.MT.col_positions[self.rsz_w + 1 :] = [
794
+ e + increment for e in islice(self.MT.col_positions, self.rsz_w + 1, None)
795
+ ]
796
+ self.MT.col_positions[self.rsz_w] = new_col_pos
797
+ new_width = self.MT.col_positions[self.rsz_w] - self.MT.col_positions[self.rsz_w - 1]
798
+ self.MT.allow_auto_resize_columns = False
799
+ self.MT.recreate_all_selection_boxes()
800
+ self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
801
+ if self.column_width_resize_func is not None and old_width != new_width:
802
+ self.column_width_resize_func(
803
+ event_dict(
804
+ name="resize",
805
+ sheet=self.PAR.name,
806
+ resized_columns={self.rsz_w - 1: {"old_size": old_width, "new_size": new_width}},
807
+ )
808
+ )
809
+
782
810
  def b1_release(self, event: object) -> None:
783
811
  if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
784
812
  r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
@@ -795,37 +823,12 @@ class ColumnHeaders(tk.Canvas):
795
823
  self.being_drawn_item = None
796
824
  self.MT.bind("<MouseWheel>", self.MT.mousewheel)
797
825
  if self.width_resizing_enabled and self.rsz_w is not None and self.currently_resizing_width:
826
+ self.drag_width_resize()
798
827
  self.currently_resizing_width = False
799
- new_col_pos = int(self.coords("rwl")[0])
800
828
  self.hide_resize_and_ctrl_lines(ctrl_lines=False)
801
- old_width = self.MT.col_positions[self.rsz_w] - self.MT.col_positions[self.rsz_w - 1]
802
- size = new_col_pos - self.MT.col_positions[self.rsz_w - 1]
803
- if size < self.MT.min_column_width:
804
- new_col_pos = ceil(self.MT.col_positions[self.rsz_w - 1] + self.MT.min_column_width)
805
- elif size > self.MT.max_column_width:
806
- new_col_pos = floor(self.MT.col_positions[self.rsz_w - 1] + self.MT.max_column_width)
807
- increment = new_col_pos - self.MT.col_positions[self.rsz_w]
808
- self.MT.col_positions[self.rsz_w + 1 :] = [
809
- e + increment for e in islice(self.MT.col_positions, self.rsz_w + 1, len(self.MT.col_positions))
810
- ]
811
- self.MT.col_positions[self.rsz_w] = new_col_pos
812
- new_width = self.MT.col_positions[self.rsz_w] - self.MT.col_positions[self.rsz_w - 1]
813
- self.MT.allow_auto_resize_columns = False
814
- self.MT.recreate_all_selection_boxes()
815
- self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
816
- if self.column_width_resize_func is not None and old_width != new_width:
817
- self.column_width_resize_func(
818
- event_dict(
819
- name="resize",
820
- sheet=self.PAR.name,
821
- resized_columns={self.rsz_w - 1: {"old_size": old_width, "new_size": new_width}},
822
- )
823
- )
824
829
  elif self.height_resizing_enabled and self.rsz_h is not None and self.currently_resizing_height:
825
830
  self.currently_resizing_height = False
826
- self.hide_resize_and_ctrl_lines(ctrl_lines=False)
827
- self.set_height(self.new_col_height, set_TL=True)
828
- self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
831
+ self.drag_height_resize()
829
832
  elif (
830
833
  self.drag_and_drop_enabled
831
834
  and self.col_selection_enabled
@@ -2173,7 +2176,16 @@ class ColumnHeaders(tk.Canvas):
2173
2176
  )
2174
2177
  edited = False
2175
2178
  if isinstance(self.MT._headers, int):
2176
- edited = self.MT.set_cell_data_undo(r=self.MT._headers, c=c, datacn=datacn, value=value, undo=True)
2179
+ disprn = self.MT.try_disprn(self.MT._headers)
2180
+ edited = self.MT.set_cell_data_undo(
2181
+ r=disprn if isinstance(disprn, int) else 0,
2182
+ c=c,
2183
+ datarn=self.MT._headers,
2184
+ datacn=datacn,
2185
+ value=value,
2186
+ undo=True,
2187
+ cell_resize=isinstance(disprn, int),
2188
+ )
2177
2189
  else:
2178
2190
  self.fix_header(datacn)
2179
2191
  if not check_input_valid or self.input_valid_for_cell(datacn, value):
@@ -1,12 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- import bisect
4
3
  import csv
5
4
  import io
6
5
  import pickle
7
6
  import re
8
7
  import tkinter as tk
9
8
  import zlib
9
+ from bisect import (
10
+ bisect_left,
11
+ )
10
12
  from collections import deque
11
13
  from collections.abc import (
12
14
  Callable,
@@ -208,6 +210,16 @@ def len_to_idx(n: int) -> int:
208
210
  return n - 1
209
211
 
210
212
 
213
+ def b_index(sorted_seq: Sequence[int], num_to_index: int) -> int:
214
+ """
215
+ Designed to be a faster way of finding the index of an int
216
+ in a sorted list of ints than list.index()
217
+ """
218
+ if (idx := bisect_left(sorted_seq, num_to_index)) == len(sorted_seq) or sorted_seq[idx] != num_to_index:
219
+ raise ValueError(f"{num_to_index} is not in Sequence")
220
+ return idx
221
+
222
+
211
223
  def get_dropdown_kwargs(
212
224
  values: list = [],
213
225
  set_value: object = None,
@@ -379,7 +391,7 @@ def get_seq_without_gaps_at_index(
379
391
  position: int,
380
392
  get_st_end: bool = False,
381
393
  ) -> tuple[int, int] | list[int]:
382
- start_idx = bisect.bisect_left(seq, position)
394
+ start_idx = bisect_left(seq, position)
383
395
  forward_gap = get_index_of_gap_in_sorted_integer_seq_forward(seq, start_idx)
384
396
  reverse_gap = get_index_of_gap_in_sorted_integer_seq_reverse(seq, start_idx)
385
397
  if forward_gap is not None:
@@ -49,6 +49,7 @@ from .formatters import (
49
49
  try_to_bool,
50
50
  )
51
51
  from .functions import (
52
+ b_index,
52
53
  consecutive_ranges,
53
54
  decompress_load,
54
55
  diff_gen,
@@ -1778,7 +1779,12 @@ class MainTable(tk.Canvas):
1778
1779
  0 if not r else self.row_positions[r + 1],
1779
1780
  )
1780
1781
 
1781
- def cell_completely_visible(self, r: int = 0, c: int = 0, separate_axes: bool = False) -> bool:
1782
+ def cell_completely_visible(
1783
+ self,
1784
+ r: int | None = 0,
1785
+ c: int | None = 0,
1786
+ separate_axes: bool = False,
1787
+ ) -> bool:
1782
1788
  cx1, cy1, cx2, cy2 = self.get_canvas_visible_area()
1783
1789
  x1, y1, x2, y2 = self.get_cell_coords(r, c)
1784
1790
  x_vis = True
@@ -1832,8 +1838,10 @@ class MainTable(tk.Canvas):
1832
1838
  run_binding_func: bool = True,
1833
1839
  ext: bool = False,
1834
1840
  ) -> int:
1835
- self.deselect("all", redraw=False)
1841
+ boxes_to_hide = tuple(self.selection_boxes)
1836
1842
  fill_iid = self.create_selection_box(r, c, r + 1, c + 1, state="hidden", ext=ext)
1843
+ for iid in boxes_to_hide:
1844
+ self.hide_selection_box(iid)
1837
1845
  if redraw:
1838
1846
  self.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
1839
1847
  if run_binding_func:
@@ -2984,12 +2992,10 @@ class MainTable(tk.Canvas):
2984
2992
  and self.selected.type_ == "cells"
2985
2993
  ):
2986
2994
  box = self.get_b1_motion_box(
2987
- *(
2988
- self.selected.row,
2989
- self.selected.column,
2990
- end_row,
2991
- end_col,
2992
- )
2995
+ self.selected.row,
2996
+ self.selected.column,
2997
+ end_row,
2998
+ end_col,
2993
2999
  )
2994
3000
  if (
2995
3001
  box is not None
@@ -3027,12 +3033,10 @@ class MainTable(tk.Canvas):
3027
3033
  and self.selected.type_ == "cells"
3028
3034
  ):
3029
3035
  box = self.get_b1_motion_box(
3030
- *(
3031
- self.selected.row,
3032
- self.selected.column,
3033
- end_row,
3034
- end_col,
3035
- )
3036
+ self.selected.row,
3037
+ self.selected.column,
3038
+ end_row,
3039
+ end_col,
3036
3040
  )
3037
3041
  if (
3038
3042
  box is not None
@@ -7457,3 +7461,21 @@ class MainTable(tk.Canvas):
7457
7461
 
7458
7462
  def datarn(self, r: int) -> int:
7459
7463
  return r if self.all_rows_displayed else self.displayed_rows[r]
7464
+
7465
+ def dispcn(self, datacn: int) -> int:
7466
+ return datacn if self.all_columns_displayed else b_index(self.displayed_columns, datacn)
7467
+
7468
+ def try_dispcn(self, datacn: int) -> int | None:
7469
+ try:
7470
+ return self.dispcn(datacn)
7471
+ except Exception:
7472
+ return None
7473
+
7474
+ def disprn(self, datarn: int) -> int:
7475
+ return datarn if self.all_rows_displayed else b_index(self.displayed_rows, datarn)
7476
+
7477
+ def try_disprn(self, datarn: int) -> int | None:
7478
+ try:
7479
+ return self.disprn(datarn)
7480
+ except Exception:
7481
+ return None
@@ -6,6 +6,7 @@ from collections.abc import Callable, Generator, Hashable, Iterator
6
6
  from functools import partial
7
7
  from typing import Literal
8
8
 
9
+
9
10
  pickle_obj = partial(pickle.dumps, protocol=pickle.HIGHEST_PROTOCOL)
10
11
 
11
12
  FontTuple = namedtuple("FontTuple", "family size style")
@@ -152,18 +153,16 @@ class Span(dict):
152
153
  redraw: bool = True,
153
154
  **kwargs,
154
155
  ) -> Span:
155
- self["widget"].format(
156
+ return self["widget"].format(
156
157
  self,
157
158
  formatter_options={"formatter": formatter_class, **formatter_options, **kwargs},
158
159
  formatter_class=formatter_class,
159
160
  redraw=redraw,
160
161
  **kwargs,
161
162
  )
162
- return self
163
163
 
164
164
  def del_format(self) -> Span:
165
- self["widget"].del_format(self)
166
- return self
165
+ return self["widget"].del_format(self)
167
166
 
168
167
  def highlight(
169
168
  self,
@@ -173,7 +172,7 @@ class Span(dict):
173
172
  overwrite: bool = False,
174
173
  redraw: bool = True,
175
174
  ) -> Span:
176
- self["widget"].highlight(
175
+ return self["widget"].highlight(
177
176
  self,
178
177
  bg=bg,
179
178
  fg=fg,
@@ -181,34 +180,74 @@ class Span(dict):
181
180
  overwrite=overwrite,
182
181
  redraw=redraw,
183
182
  )
184
- return self
185
183
 
186
184
  def dehighlight(self, redraw: bool = True) -> Span:
187
- self["widget"].dehighlight(self, redraw=redraw)
185
+ return self["widget"].dehighlight(self, redraw=redraw)
188
186
 
189
187
  del_highlight = dehighlight
190
188
 
191
189
  def readonly(self, readonly: bool = True) -> Span:
192
- self["widget"].readonly(self, readonly=readonly)
193
- return self
190
+ return self["widget"].readonly(self, readonly=readonly)
194
191
 
195
- def dropdown(self, *args, **kwargs) -> Span:
196
- self["widget"].dropdown(self, *args, **kwargs)
192
+ def dropdown(
193
+ self,
194
+ values: list = [],
195
+ edit_data: bool = True,
196
+ set_values: dict[tuple[int, int], object] = {},
197
+ set_value: object = None,
198
+ state: str = "normal",
199
+ redraw: bool = True,
200
+ selection_function: Callable | None = None,
201
+ modified_function: Callable | None = None,
202
+ search_function: Callable | None = None,
203
+ validate_input: bool = True,
204
+ text: None | str = None,
205
+ ) -> Span:
206
+ return self["widget"].dropdown(
207
+ self,
208
+ values=values,
209
+ edit_data=edit_data,
210
+ set_values=set_values,
211
+ set_value=set_value,
212
+ state=state,
213
+ redraw=redraw,
214
+ selection_function=selection_function,
215
+ modified_function=modified_function,
216
+ search_function=search_function,
217
+ validate_input=validate_input,
218
+ text=text,
219
+ )
197
220
 
198
221
  def del_dropdown(self) -> Span:
199
- self["widget"].del_dropdown(self)
222
+ return self["widget"].del_dropdown(self)
200
223
 
201
- def checkbox(self, *args, **kwargs) -> Span:
202
- self["widget"].dropdown(self, *args, **kwargs)
224
+ def checkbox(
225
+ self,
226
+ edit_data: bool = True,
227
+ checked: bool | None = None,
228
+ state: str = "normal",
229
+ redraw: bool = True,
230
+ check_function: Callable | None = None,
231
+ text: str = "",
232
+ ) -> Span:
233
+ return self["widget"].checkbox(
234
+ self,
235
+ edit_data=edit_data,
236
+ checked=checked,
237
+ state=state,
238
+ redraw=redraw,
239
+ check_function=check_function,
240
+ text=text,
241
+ )
203
242
 
204
243
  def del_checkbox(self) -> Span:
205
- self["widget"].del_checkbox(self)
244
+ return self["widget"].del_checkbox(self)
206
245
 
207
246
  def align(self, align: str | None, redraw: bool = True) -> Span:
208
- self["widget"].align(self, align=align, redraw=redraw)
247
+ return self["widget"].align(self, align=align, redraw=redraw)
209
248
 
210
249
  def del_align(self, redraw: bool = True) -> Span:
211
- self["widget"].del_align(self, redraw=redraw)
250
+ return self["widget"].del_align(self, redraw=redraw)
212
251
 
213
252
  def clear(self, undo: bool | None = None, redraw: bool = True) -> Span:
214
253
  if undo is not None:
@@ -304,7 +343,7 @@ class Span(dict):
304
343
  self["transposed"] = not self["transposed"]
305
344
  return self
306
345
 
307
- def expand(self, direction: str = "both") -> Span:
346
+ def expand(self, direction: Literal["both", "table", "down", "right"] = "both") -> Span:
308
347
  if direction == "both" or direction == "table":
309
348
  self["upto_r"], self["upto_c"] = None, None
310
349
  elif direction == "down":
@@ -489,7 +489,6 @@ class RowIndex(tk.Canvas):
489
489
  if x < self.MT.min_column_width:
490
490
  x = int(self.MT.min_column_width)
491
491
  self.new_row_width = x
492
- self.create_resize_line(x, y1, x, y2, width=1, fill=self.PAR.ops.resizing_line_fg, tag="rwl")
493
492
  elif self.MT.identify_row(y=event.y, allow_end=False) is None:
494
493
  self.MT.deselect("all")
495
494
  elif self.row_selection_enabled and self.rsz_h is None and self.rsz_w is None:
@@ -549,22 +548,21 @@ class RowIndex(tk.Canvas):
549
548
  fill=self.PAR.ops.resizing_line_fg,
550
549
  tag="rhl2",
551
550
  )
551
+ self.drag_height_resize()
552
552
  elif self.width_resizing_enabled and self.rsz_w is not None and self.currently_resizing_width:
553
553
  evx = event.x
554
- self.hide_resize_and_ctrl_lines(ctrl_lines=False)
555
554
  if evx > self.current_width:
556
555
  x = self.MT.canvasx(evx - self.current_width)
557
556
  if evx > self.MT.max_index_width:
558
557
  evx = int(self.MT.max_index_width)
559
558
  x = self.MT.canvasx(evx - self.current_width)
560
559
  self.new_row_width = evx
561
- self.MT.create_resize_line(x, y1, x, y2, width=1, fill=self.PAR.ops.resizing_line_fg, tag="rwl")
562
560
  else:
563
561
  x = evx
564
562
  if x < self.MT.min_column_width:
565
563
  x = int(self.MT.min_column_width)
566
564
  self.new_row_width = x
567
- self.create_resize_line(x, y1, x, y2, width=1, fill=self.PAR.ops.resizing_line_fg, tag="rwl")
565
+ self.drag_width_resize()
568
566
  if (
569
567
  self.drag_and_drop_enabled
570
568
  and self.row_selection_enabled
@@ -783,6 +781,36 @@ class RowIndex(tk.Canvas):
783
781
  and event.x < self.MT.index_txt_height + 4
784
782
  )
785
783
 
784
+ def drag_width_resize(self) -> None:
785
+ self.set_width(self.new_row_width, set_TL=True)
786
+ self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
787
+
788
+ def drag_height_resize(self) -> None:
789
+ new_row_pos = int(self.coords("rhl")[1])
790
+ old_height = self.MT.row_positions[self.rsz_h] - self.MT.row_positions[self.rsz_h - 1]
791
+ size = new_row_pos - self.MT.row_positions[self.rsz_h - 1]
792
+ if size < self.MT.min_row_height:
793
+ new_row_pos = ceil(self.MT.row_positions[self.rsz_h - 1] + self.MT.min_row_height)
794
+ elif size > self.MT.max_row_height:
795
+ new_row_pos = floor(self.MT.row_positions[self.rsz_h - 1] + self.MT.max_row_height)
796
+ increment = new_row_pos - self.MT.row_positions[self.rsz_h]
797
+ self.MT.row_positions[self.rsz_h + 1 :] = [
798
+ e + increment for e in islice(self.MT.row_positions, self.rsz_h + 1, None)
799
+ ]
800
+ self.MT.row_positions[self.rsz_h] = new_row_pos
801
+ new_height = self.MT.row_positions[self.rsz_h] - self.MT.row_positions[self.rsz_h - 1]
802
+ self.MT.allow_auto_resize_rows = False
803
+ self.MT.recreate_all_selection_boxes()
804
+ self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
805
+ if self.row_height_resize_func is not None and old_height != new_height:
806
+ self.row_height_resize_func(
807
+ event_dict(
808
+ name="resize",
809
+ sheet=self.PAR.name,
810
+ resized_rows={self.rsz_h - 1: {"old_size": old_height, "new_size": new_height}},
811
+ )
812
+ )
813
+
786
814
  def b1_release(self, event: object) -> None:
787
815
  if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
788
816
  r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
@@ -799,37 +827,12 @@ class RowIndex(tk.Canvas):
799
827
  self.being_drawn_item = None
800
828
  self.MT.bind("<MouseWheel>", self.MT.mousewheel)
801
829
  if self.height_resizing_enabled and self.rsz_h is not None and self.currently_resizing_height:
830
+ self.drag_height_resize()
802
831
  self.currently_resizing_height = False
803
- new_row_pos = int(self.coords("rhl")[1])
804
832
  self.hide_resize_and_ctrl_lines(ctrl_lines=False)
805
- old_height = self.MT.row_positions[self.rsz_h] - self.MT.row_positions[self.rsz_h - 1]
806
- size = new_row_pos - self.MT.row_positions[self.rsz_h - 1]
807
- if size < self.MT.min_row_height:
808
- new_row_pos = ceil(self.MT.row_positions[self.rsz_h - 1] + self.MT.min_row_height)
809
- elif size > self.MT.max_row_height:
810
- new_row_pos = floor(self.MT.row_positions[self.rsz_h - 1] + self.MT.max_row_height)
811
- increment = new_row_pos - self.MT.row_positions[self.rsz_h]
812
- self.MT.row_positions[self.rsz_h + 1 :] = [
813
- e + increment for e in islice(self.MT.row_positions, self.rsz_h + 1, len(self.MT.row_positions))
814
- ]
815
- self.MT.row_positions[self.rsz_h] = new_row_pos
816
- new_height = self.MT.row_positions[self.rsz_h] - self.MT.row_positions[self.rsz_h - 1]
817
- self.MT.allow_auto_resize_rows = False
818
- self.MT.recreate_all_selection_boxes()
819
- self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
820
- if self.row_height_resize_func is not None and old_height != new_height:
821
- self.row_height_resize_func(
822
- event_dict(
823
- name="resize",
824
- sheet=self.PAR.name,
825
- resized_rows={self.rsz_h - 1: {"old_size": old_height, "new_size": new_height}},
826
- )
827
- )
828
833
  elif self.width_resizing_enabled and self.rsz_w is not None and self.currently_resizing_width:
829
834
  self.currently_resizing_width = False
830
- self.hide_resize_and_ctrl_lines(ctrl_lines=False)
831
- self.set_width(self.new_row_width, set_TL=True)
832
- self.MT.main_table_redraw_grid_and_text(redraw_header=True, redraw_row_index=True)
835
+ self.drag_width_resize()
833
836
  if (
834
837
  self.drag_and_drop_enabled
835
838
  and self.MT.anything_selected(exclude_cells=True, exclude_columns=True)
@@ -1054,7 +1057,7 @@ class RowIndex(tk.Canvas):
1054
1057
  align = self.align
1055
1058
  if align == "w":
1056
1059
  w += self.MT.index_txt_height
1057
- w += self.get_treeview_indent(self.MT._row_index[datarn].iid) + 5
1060
+ w += self.get_treeview_indent(self.MT._row_index[datarn].iid) + 10
1058
1061
  return w, h
1059
1062
 
1060
1063
  def get_row_text_height(
@@ -1134,9 +1137,6 @@ class RowIndex(tk.Canvas):
1134
1137
  isinstance(self.MT._row_index, int) and self.MT._row_index >= len(self.MT.data)
1135
1138
  ):
1136
1139
  return w
1137
- qconf = self.MT.txt_measure_canvas.itemconfig
1138
- qbbox = self.MT.txt_measure_canvas.bbox
1139
- qtxtm = self.MT.txt_measure_canvas_text
1140
1140
  if only_rows:
1141
1141
  iterable = only_rows
1142
1142
  elif self.MT.all_rows_displayed:
@@ -1146,19 +1146,8 @@ class RowIndex(tk.Canvas):
1146
1146
  iterable = range(len(self.MT.data))
1147
1147
  else:
1148
1148
  iterable = self.MT.displayed_rows
1149
- if (
1150
- isinstance(self.MT._row_index, list)
1151
- and (tw := max(map(itemgetter(0), map(self.get_cell_dimensions, iterable)), default=w)) > w
1152
- ):
1153
- w = tw
1154
- elif isinstance(self.MT._row_index, int):
1155
- datacn = self.MT._row_index
1156
- for datarn in iterable:
1157
- if txt := self.MT.get_valid_cell_data_as_str(datarn, datacn, get_displayed=True):
1158
- qconf(qtxtm, text=txt)
1159
- b = qbbox(qtxtm)
1160
- if (tw := b[2] - b[0] + 10) > w:
1161
- w = tw
1149
+ if (new_w := max(map(itemgetter(0), map(self.get_cell_dimensions, iterable)), default=w)) > w:
1150
+ w = new_w
1162
1151
  if w > self.MT.max_index_width:
1163
1152
  w = int(self.MT.max_index_width)
1164
1153
  return w
@@ -1713,7 +1702,6 @@ class RowIndex(tk.Canvas):
1713
1702
  lns = self.get_valid_cell_data_as_str(datarn, fix=False)
1714
1703
  if not lns:
1715
1704
  continue
1716
- lns = lns.split("\n")
1717
1705
  draw_y = rtopgridln + self.MT.index_first_ln_ins
1718
1706
  if mw > 5:
1719
1707
  draw_y = rtopgridln + self.MT.index_first_ln_ins
@@ -1721,6 +1709,7 @@ class RowIndex(tk.Canvas):
1721
1709
  if start_ln < 0:
1722
1710
  start_ln = 0
1723
1711
  draw_y += start_ln * self.MT.index_xtra_lines_increment
1712
+ lns = lns.split("\n")
1724
1713
  if draw_y + self.MT.index_half_txt_height - 1 <= rbotgridln and len(lns) > start_ln:
1725
1714
  for txt in islice(lns, start_ln, None):
1726
1715
  if self.hidd_text:
@@ -2307,7 +2296,16 @@ class RowIndex(tk.Canvas):
2307
2296
  )
2308
2297
  edited = False
2309
2298
  if isinstance(self.MT._row_index, int):
2310
- edited = self.MT.set_cell_data_undo(r=r, c=self.MT._row_index, datarn=datarn, value=value, undo=True)
2299
+ dispcn = self.MT.try_dispcn(self.MT._row_index)
2300
+ edited = self.MT.set_cell_data_undo(
2301
+ r=r,
2302
+ c=dispcn if isinstance(dispcn, int) else 0,
2303
+ datarn=datarn,
2304
+ datacn=self.MT._row_index,
2305
+ value=value,
2306
+ undo=True,
2307
+ cell_resize=isinstance(dispcn, int),
2308
+ )
2311
2309
  else:
2312
2310
  self.fix_index(datarn)
2313
2311
  if not check_input_valid or self.input_valid_for_cell(datarn, value):
@@ -2442,7 +2440,7 @@ class RowIndex(tk.Canvas):
2442
2440
  elif isinstance(self.MT._row_index, int):
2443
2441
  value = (
2444
2442
  not self.MT.data[datarn][self.MT._row_index]
2445
- if type(self.MT.data[datarn][self.MT._row_index], bool)
2443
+ if isinstance(self.MT.data[datarn][self.MT._row_index], bool)
2446
2444
  else False
2447
2445
  )
2448
2446
  else:
@@ -2487,8 +2485,7 @@ class RowIndex(tk.Canvas):
2487
2485
  if iid not in self.tree_open_ids:
2488
2486
  return False
2489
2487
  return True
2490
- else:
2491
- return all(iid in self.tree_open_ids for iid in self.get_iid_ancestors(iid))
2488
+ return all(map(self.tree_open_ids.__contains__, self.get_iid_ancestors(iid)))
2492
2489
 
2493
2490
  def get_iid_ancestors(self, iid: str) -> Generator[str]:
2494
2491
  if self.tree[iid].parent:
@@ -1557,6 +1557,14 @@ class Sheet(tk.Frame):
1557
1557
  def data(self, value: list[list[object]]) -> None:
1558
1558
  self.data_reference(value)
1559
1559
 
1560
+ def new_tksheet_event(self) -> EventDataDict:
1561
+ return event_dict(
1562
+ name="",
1563
+ sheet=self.name,
1564
+ widget=self,
1565
+ selected=self.MT.selected,
1566
+ )
1567
+
1560
1568
  def set_data(
1561
1569
  self,
1562
1570
  *key: CreateSpanTypes,
@@ -2185,6 +2193,7 @@ class Sheet(tk.Frame):
2185
2193
  emit_event: bool = False,
2186
2194
  redraw: bool = True,
2187
2195
  ) -> EventDataDict:
2196
+ self.MT.deselect("all", redraw=False)
2188
2197
  rows = [rows] if isinstance(rows, int) else sorted(rows)
2189
2198
  event_data = event_dict(
2190
2199
  name="delete_rows",
@@ -2213,7 +2222,6 @@ class Sheet(tk.Frame):
2213
2222
  self.MT.undo_stack.append(pickled_event_dict(event_data))
2214
2223
  if emit_event:
2215
2224
  self.emit_event("<<SheetModified>>", event_data)
2216
- self.MT.deselect("all", redraw=False)
2217
2225
  self.set_refresh_timer(redraw)
2218
2226
  return event_data
2219
2227
 
@@ -2227,6 +2235,7 @@ class Sheet(tk.Frame):
2227
2235
  emit_event: bool = False,
2228
2236
  redraw: bool = True,
2229
2237
  ) -> EventDataDict:
2238
+ self.MT.deselect("all", redraw=False)
2230
2239
  columns = [columns] if isinstance(columns, int) else sorted(columns)
2231
2240
  event_data = event_dict(
2232
2241
  name="delete_columns",
@@ -2255,7 +2264,6 @@ class Sheet(tk.Frame):
2255
2264
  self.MT.undo_stack.append(pickled_event_dict(event_data))
2256
2265
  if emit_event:
2257
2266
  self.emit_event("<<SheetModified>>", event_data)
2258
- self.MT.deselect("all", redraw=False)
2259
2267
  self.set_refresh_timer(redraw)
2260
2268
  return event_data
2261
2269
 
@@ -2557,10 +2565,12 @@ class Sheet(tk.Frame):
2557
2565
  redraw: bool = True,
2558
2566
  selection_function: Callable | None = None,
2559
2567
  modified_function: Callable | None = None,
2560
- search_function: Callable = dropdown_search_function,
2568
+ search_function: Callable | None = None,
2561
2569
  validate_input: bool = True,
2562
2570
  text: None | str = None,
2563
2571
  ) -> Span:
2572
+ if not search_function:
2573
+ search_function = dropdown_search_function
2564
2574
  v = set_value if set_value is not None else values[0] if values else ""
2565
2575
  kwargs = {
2566
2576
  "values": values,
@@ -3902,7 +3912,7 @@ class Sheet(tk.Frame):
3902
3912
  idx = bisect_left(self.MT.displayed_columns, column)
3903
3913
  if len(self.MT.displayed_columns) == idx or self.MT.displayed_columns[idx] != column:
3904
3914
  self.MT.displayed_columns.insert(idx, column)
3905
- cws.insert(idx, self.MT.saved_column_widths.pop(column, self.PAR.ops.default_column_width))
3915
+ cws.insert(idx, self.MT.saved_column_widths.pop(column, self.ops.default_column_width))
3906
3916
  self.MT.set_col_positions(cws)
3907
3917
  if deselect_all:
3908
3918
  self.MT.deselect(redraw=False)
@@ -163,13 +163,13 @@ theme_dark: dict[str, str] = DotDict({
163
163
  "header_border_fg": "#505054",
164
164
  "header_grid_fg": "#8C8C8C",
165
165
  "header_fg": "gray70",
166
- "header_selected_cells_bg": "#545454",
166
+ "header_selected_cells_bg": "#4b4b4b",
167
167
  "header_selected_cells_fg": "#6aa2fc",
168
168
  "index_bg": "#141414",
169
169
  "index_border_fg": "#505054",
170
170
  "index_grid_fg": "#8C8C8C",
171
171
  "index_fg": "gray70",
172
- "index_selected_cells_bg": "#545454",
172
+ "index_selected_cells_bg": "#4b4b4b",
173
173
  "index_selected_cells_fg": "#6aa2fc",
174
174
  "top_left_bg": "#28282a",
175
175
  "top_left_fg": "#505054",
@@ -238,13 +238,13 @@ theme_black: dict[str, str] = DotDict({
238
238
  "header_border_fg": "#505054",
239
239
  "header_grid_fg": "#8C8C8C",
240
240
  "header_fg": "#FBB86C",
241
- "header_selected_cells_bg": "#545454",
241
+ "header_selected_cells_bg": "#4b4b4b",
242
242
  "header_selected_cells_fg": "#FBB86C",
243
243
  "index_bg": "#000000",
244
244
  "index_border_fg": "#505054",
245
245
  "index_grid_fg": "#8C8C8C",
246
246
  "index_fg": "#FBB86C",
247
- "index_selected_cells_bg": "#545454",
247
+ "index_selected_cells_bg": "#4b4b4b",
248
248
  "index_selected_cells_fg": "#FBB86C",
249
249
  "top_left_bg": "#141416",
250
250
  "top_left_fg": "#505054",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tksheet
3
- Version: 7.2.10
3
+ Version: 7.2.12
4
4
  Summary: Tkinter table / sheet widget
5
5
  Author-email: ragardner <github@ragardner.simplelogin.com>
6
6
  License: Copyright (c) 2019 ragardner and open source contributors
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes