tksheet 7.2.8__tar.gz → 7.2.10__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.8/tksheet.egg-info → tksheet-7.2.10}/PKG-INFO +1 -1
  2. {tksheet-7.2.8 → tksheet-7.2.10}/pyproject.toml +1 -1
  3. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/__init__.py +1 -1
  4. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/column_headers.py +20 -19
  5. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/functions.py +1 -1
  6. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/main_table.py +81 -70
  7. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/row_index.py +40 -32
  8. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/sheet.py +122 -58
  9. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/top_left_rectangle.py +9 -10
  10. {tksheet-7.2.8 → tksheet-7.2.10/tksheet.egg-info}/PKG-INFO +1 -1
  11. {tksheet-7.2.8 → tksheet-7.2.10}/LICENSE.txt +0 -0
  12. {tksheet-7.2.8 → tksheet-7.2.10}/README.md +0 -0
  13. {tksheet-7.2.8 → tksheet-7.2.10}/setup.cfg +0 -0
  14. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/colors.py +0 -0
  15. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/formatters.py +0 -0
  16. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/other_classes.py +0 -0
  17. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/sheet_options.py +0 -0
  18. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/text_editor.py +0 -0
  19. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/themes.py +0 -0
  20. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/types.py +0 -0
  21. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet/vars.py +0 -0
  22. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet.egg-info/SOURCES.txt +0 -0
  23. {tksheet-7.2.8 → tksheet-7.2.10}/tksheet.egg-info/dependency_links.txt +0 -0
  24. {tksheet-7.2.8 → tksheet-7.2.10}/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.8
3
+ Version: 7.2.10
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.8"
9
+ version = "7.2.10"
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.8"
7
+ __version__ = "7.2.10"
8
8
 
9
9
  from .colors import (
10
10
  color_map,
@@ -946,7 +946,7 @@ class ColumnHeaders(tk.Canvas):
946
946
  run_binding_func: bool = True,
947
947
  ext: bool = False,
948
948
  ) -> int:
949
- boxes_to_hide = tuple(iid for iid in self.MT.selection_boxes)
949
+ boxes_to_hide = tuple(self.MT.selection_boxes)
950
950
  fill_iid = self.MT.create_selection_box(0, c, len(self.MT.row_positions) - 1, c + 1, "columns", ext=ext)
951
951
  for iid in boxes_to_hide:
952
952
  self.MT.hide_selection_box(iid)
@@ -989,7 +989,7 @@ class ColumnHeaders(tk.Canvas):
989
989
  y1,
990
990
  x2,
991
991
  y2,
992
- radius=8 if self.PAR.ops.rounded_boxes else 0,
992
+ radius=5 if self.PAR.ops.rounded_boxes else 0,
993
993
  )
994
994
  if isinstance(iid, int):
995
995
  self.coords(iid, coords)
@@ -1314,24 +1314,23 @@ class ColumnHeaders(tk.Canvas):
1314
1314
  if open_:
1315
1315
  # up arrow
1316
1316
  points = (
1317
- x2 - 3 - small_mod - small_mod - small_mod - small_mod,
1317
+ x2 - 4 - small_mod - small_mod - small_mod - small_mod,
1318
1318
  y1 + mid_y + small_mod,
1319
- x2 - 3 - small_mod - small_mod,
1319
+ x2 - 4 - small_mod - small_mod,
1320
1320
  y1 + mid_y - small_mod,
1321
- x2 - 3,
1321
+ x2 - 4,
1322
1322
  y1 + mid_y + small_mod,
1323
1323
  )
1324
1324
  else:
1325
1325
  # down arrow
1326
1326
  points = (
1327
- x2 - 3 - small_mod - small_mod - small_mod - small_mod,
1327
+ x2 - 4 - small_mod - small_mod - small_mod - small_mod,
1328
1328
  y1 + mid_y - small_mod,
1329
- x2 - 3 - small_mod - small_mod,
1329
+ x2 - 4 - small_mod - small_mod,
1330
1330
  y1 + mid_y + small_mod,
1331
- x2 - 3,
1331
+ x2 - 4,
1332
1332
  y1 + mid_y - small_mod,
1333
1333
  )
1334
-
1335
1334
  if self.hidd_dropdown:
1336
1335
  t, sh = self.hidd_dropdown.popitem()
1337
1336
  self.coords(t, points)
@@ -1341,10 +1340,13 @@ class ColumnHeaders(tk.Canvas):
1341
1340
  self.itemconfig(t, fill=fill, tag=tag, state="normal")
1342
1341
  self.lift(t)
1343
1342
  else:
1344
- t = self.create_polygon(
1343
+ t = self.create_line(
1345
1344
  points,
1346
1345
  fill=fill,
1347
1346
  tag=tag,
1347
+ width=2,
1348
+ capstyle=tk.ROUND,
1349
+ joinstyle=tk.BEVEL,
1348
1350
  )
1349
1351
  self.disp_dropdown[t] = True
1350
1352
 
@@ -1758,8 +1760,7 @@ class ColumnHeaders(tk.Canvas):
1758
1760
  if self.text_editor.open and c == self.text_editor.column:
1759
1761
  self.text_editor.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
1760
1762
  return
1761
- if self.text_editor.open:
1762
- self.hide_text_editor()
1763
+ self.hide_text_editor()
1763
1764
  if not self.MT.see(r=0, c=c, keep_yscroll=True, check_cell_visibility=True):
1764
1765
  self.MT.refresh()
1765
1766
  x = self.MT.col_positions[c] + 1
@@ -1905,14 +1906,12 @@ class ColumnHeaders(tk.Canvas):
1905
1906
  )
1906
1907
  # self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
1907
1908
 
1908
- def hide_text_editor(self, reason: None | str = None) -> None:
1909
+ def hide_text_editor(self) -> None:
1909
1910
  if self.text_editor.open:
1910
1911
  for binding in text_editor_to_unbind:
1911
1912
  self.text_editor.tktext.unbind(binding)
1912
1913
  self.itemconfig(self.text_editor.canvas_id, state="hidden")
1913
1914
  self.text_editor.open = False
1914
- if reason == "Escape":
1915
- self.focus_set()
1916
1915
 
1917
1916
  # c is displayed col
1918
1917
  def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
@@ -1931,6 +1930,7 @@ class ColumnHeaders(tk.Canvas):
1931
1930
  return "break"
1932
1931
  if event.keysym == "Escape":
1933
1932
  self.hide_text_editor_and_dropdown()
1933
+ self.focus_set()
1934
1934
  return
1935
1935
  # setting cell data with text editor value
1936
1936
  text_editor_value = self.text_editor.get()
@@ -2009,7 +2009,7 @@ class ColumnHeaders(tk.Canvas):
2009
2009
  dd_window.search_and_see(event)
2010
2010
 
2011
2011
  def open_dropdown_window(self, c: int, event: object = None) -> None:
2012
- self.hide_text_editor("Escape")
2012
+ self.hide_text_editor()
2013
2013
  kwargs = self.get_cell_kwargs(self.MT.datacn(c), key="dropdown")
2014
2014
  if kwargs["state"] == "normal":
2015
2015
  if not self.open_text_editor(event=event, c=c, dropdown=True):
@@ -2073,8 +2073,9 @@ class ColumnHeaders(tk.Canvas):
2073
2073
  return
2074
2074
  redraw = False
2075
2075
  else:
2076
- self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(c))
2077
2076
  self.update_idletasks()
2077
+ self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(c))
2078
+ self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
2078
2079
  self.dropdown.window.focus_set()
2079
2080
  redraw = True
2080
2081
  self.dropdown.open = True
@@ -2114,12 +2115,12 @@ class ColumnHeaders(tk.Canvas):
2114
2115
  edited = self.set_cell_data_undo(c, datacn=datacn, value=selection, redraw=not redraw)
2115
2116
  if edited:
2116
2117
  try_binding(self.extra_end_edit_cell_func, event_data)
2117
- self.focus_set()
2118
2118
  self.MT.recreate_all_selection_boxes()
2119
+ self.focus_set()
2119
2120
  self.hide_text_editor_and_dropdown(redraw=redraw)
2120
2121
 
2121
2122
  def hide_text_editor_and_dropdown(self, redraw: bool = True) -> None:
2122
- self.hide_text_editor("Escape")
2123
+ self.hide_text_editor()
2123
2124
  self.hide_dropdown_window()
2124
2125
  if redraw:
2125
2126
  self.MT.refresh()
@@ -545,7 +545,7 @@ def rounded_box_coords(
545
545
  y1: float,
546
546
  x2: float,
547
547
  y2: float,
548
- radius: int = 8,
548
+ radius: int = 5,
549
549
  ) -> tuple[float]:
550
550
  return (
551
551
  x1 + radius,
@@ -25,6 +25,7 @@ from itertools import (
25
25
  accumulate,
26
26
  chain,
27
27
  cycle,
28
+ filterfalse,
28
29
  islice,
29
30
  repeat,
30
31
  )
@@ -696,8 +697,9 @@ class MainTable(tk.Canvas):
696
697
  selected=self.selected,
697
698
  )
698
699
  if self.selected:
699
- selected_r = self.selected.row
700
- selected_c = self.selected.column
700
+ selected_r = self.selected.box.from_r
701
+ selected_c = self.selected.box.from_c
702
+ curr_coords = (self.selected.row, self.selected.column)
701
703
  elif not self.selected and not self.PAR.ops.paste_can_expand_x and not self.PAR.ops.paste_can_expand_y:
702
704
  return
703
705
  else:
@@ -710,6 +712,7 @@ class MainTable(tk.Canvas):
710
712
  selected_c, selected_r = len(self.col_positions) - 1, 0
711
713
  elif len(self.row_positions) > 1 and len(self.col_positions) > 1:
712
714
  selected_c, selected_r = 0, len(self.row_positions) - 1
715
+ curr_coords = (selected_r, selected_c)
713
716
  try:
714
717
  data = get_data_from_clipboard(
715
718
  widget=self,
@@ -915,13 +918,17 @@ class MainTable(tk.Canvas):
915
918
  else:
916
919
  selboxc = selected_c_adjusted_new_data_numcols
917
920
  self.deselect("all", redraw=False)
918
- self.create_selection_box(
919
- selected_r,
920
- selected_c,
921
- selboxr,
922
- selboxc,
923
- "cells",
924
- run_binding=True,
921
+ self.set_currently_selected(
922
+ *curr_coords,
923
+ item=self.create_selection_box(
924
+ selected_r,
925
+ selected_c,
926
+ selboxr,
927
+ selboxc,
928
+ type_="cells",
929
+ set_current=False,
930
+ run_binding=True,
931
+ ),
925
932
  )
926
933
  event_data["selection_boxes"] = self.get_boxes()
927
934
  event_data["selected"] = self.selected
@@ -1789,9 +1796,7 @@ class MainTable(tk.Canvas):
1789
1796
  def cell_visible(self, r: int = 0, c: int = 0) -> bool:
1790
1797
  cx1, cy1, cx2, cy2 = self.get_canvas_visible_area()
1791
1798
  x1, y1, x2, y2 = self.get_cell_coords(r, c)
1792
- if x1 <= cx2 or y1 <= cy2 or x2 >= cx1 or y2 >= cy1:
1793
- return True
1794
- return False
1799
+ return x1 <= cx2 or y1 <= cy2 or x2 >= cx1 or y2 >= cy1
1795
1800
 
1796
1801
  def select_all(self, redraw: bool = True, run_binding_func: bool = True) -> None:
1797
1802
  selected = self.selected
@@ -3773,11 +3778,10 @@ class MainTable(tk.Canvas):
3773
3778
  colpos = self.PAR.ops.default_column_width
3774
3779
  if isinstance(ncols, int):
3775
3780
  self.set_col_positions(itr=repeat(colpos, ncols))
3781
+ elif self.all_columns_displayed:
3782
+ self.set_col_positions(itr=repeat(colpos, self.total_data_cols()))
3776
3783
  else:
3777
- if self.all_columns_displayed:
3778
- self.set_col_positions(itr=repeat(colpos, self.total_data_cols()))
3779
- else:
3780
- self.set_col_positions(itr=repeat(colpos, len(self.displayed_columns)))
3784
+ self.set_col_positions(itr=repeat(colpos, len(self.displayed_columns)))
3781
3785
 
3782
3786
  def set_row_positions(self, itr: Iterator[float]) -> None:
3783
3787
  self.row_positions = list(accumulate(chain([0], itr)))
@@ -3786,11 +3790,10 @@ class MainTable(tk.Canvas):
3786
3790
  rowpos = self.get_default_row_height()
3787
3791
  if isinstance(nrows, int):
3788
3792
  self.set_row_positions(itr=repeat(rowpos, nrows))
3793
+ elif self.all_rows_displayed:
3794
+ self.set_row_positions(itr=repeat(rowpos, self.total_data_rows()))
3789
3795
  else:
3790
- if self.all_rows_displayed:
3791
- self.set_row_positions(itr=repeat(rowpos, self.total_data_rows()))
3792
- else:
3793
- self.set_row_positions(itr=repeat(rowpos, len(self.displayed_rows)))
3796
+ self.set_row_positions(itr=repeat(rowpos, len(self.displayed_rows)))
3794
3797
 
3795
3798
  def del_col_position(self, idx: int, deselect_all: bool = False):
3796
3799
  if deselect_all:
@@ -4453,7 +4456,7 @@ class MainTable(tk.Canvas):
4453
4456
  if isinstance(displayed_rows, list):
4454
4457
  self.displayed_rows = displayed_rows
4455
4458
  elif not self.all_rows_displayed:
4456
- # push displayed indexes by one for every inserted column
4459
+ # push displayed indexes by one for every inserted row
4457
4460
  self.displayed_rows.sort()
4458
4461
  # highest index is first in rows
4459
4462
  up_to = len(self.displayed_rows)
@@ -4718,9 +4721,10 @@ class MainTable(tk.Canvas):
4718
4721
  named_spans=self.get_spans_to_del_from_cols(cols=cols_set),
4719
4722
  )
4720
4723
  if not self.all_columns_displayed:
4721
- self.displayed_columns = [c for c in self.displayed_columns if c not in cols_set]
4722
- for c in cols:
4723
- self.displayed_columns = [dc if c > dc else dc - 1 for dc in self.displayed_columns]
4724
+ self.displayed_columns = [
4725
+ c if not (num := bisect_left(cols, c)) else c - num
4726
+ for c in filterfalse(cols_set.__contains__, self.displayed_columns)
4727
+ ]
4724
4728
  return event_data
4725
4729
 
4726
4730
  def delete_columns_displayed(self, cols: list, event_data: dict) -> EventDataDict:
@@ -4773,9 +4777,10 @@ class MainTable(tk.Canvas):
4773
4777
  named_spans=self.get_spans_to_del_from_rows(rows=rows_set),
4774
4778
  )
4775
4779
  if not self.all_rows_displayed:
4776
- self.displayed_rows = [r for r in self.displayed_rows if r not in rows_set]
4777
- for r in rows:
4778
- self.displayed_rows = [dr if r > dr else dr - 1 for dr in self.displayed_rows]
4780
+ self.displayed_rows = [
4781
+ r if not (num := bisect_left(rows, r)) else r - num
4782
+ for r in filterfalse(rows_set.__contains__, self.displayed_rows)
4783
+ ]
4779
4784
  return event_data
4780
4785
 
4781
4786
  def delete_rows_displayed(self, rows: list, event_data: dict) -> EventDataDict:
@@ -4847,20 +4852,23 @@ class MainTable(tk.Canvas):
4847
4852
  ) -> list[int] | None:
4848
4853
  if rows is None and all_rows_displayed is None:
4849
4854
  return list(range(self.total_data_rows())) if self.all_rows_displayed else self.displayed_rows
4850
- total_data_rows = None
4851
- if (rows is not None and rows != self.displayed_rows) or (all_rows_displayed and not self.all_rows_displayed):
4852
- self.purge_undo_and_redo_stack()
4853
4855
  if rows is not None and rows != self.displayed_rows:
4856
+ self.purge_undo_and_redo_stack()
4854
4857
  self.displayed_rows = sorted(rows)
4855
- if all_rows_displayed:
4856
- if not self.all_rows_displayed:
4857
- total_data_rows = self.total_data_rows()
4858
- self.displayed_rows = list(range(total_data_rows))
4859
- self.all_rows_displayed = True
4860
- elif all_rows_displayed is not None and not all_rows_displayed:
4861
- self.all_rows_displayed = False
4858
+ # setting all_rows_displayed
4859
+ if all_rows_displayed is not None:
4860
+ # setting it to True and it's currently False
4861
+ if all_rows_displayed and not self.all_rows_displayed:
4862
+ self.purge_undo_and_redo_stack()
4863
+ self.all_rows_displayed = True
4864
+ # setting it to False and it's currently True
4865
+ elif not all_rows_displayed and self.all_rows_displayed:
4866
+ # if rows is None then displayed_rows needs to be reset
4867
+ if rows is None:
4868
+ self.displayed_rows = list(range(self.total_data_rows()))
4869
+ self.all_rows_displayed = False
4862
4870
  if reset_row_positions:
4863
- self.reset_row_positions(nrows=total_data_rows)
4871
+ self.reset_row_positions()
4864
4872
  if deselect_all:
4865
4873
  self.deselect("all", redraw=False)
4866
4874
 
@@ -4873,22 +4881,23 @@ class MainTable(tk.Canvas):
4873
4881
  ) -> list[int] | None:
4874
4882
  if columns is None and all_columns_displayed is None:
4875
4883
  return list(range(self.total_data_cols())) if self.all_columns_displayed else self.displayed_columns
4876
- total_data_cols = None
4877
- if (columns is not None and columns != self.displayed_columns) or (
4878
- all_columns_displayed and not self.all_columns_displayed
4879
- ):
4880
- self.purge_undo_and_redo_stack()
4881
4884
  if columns is not None and columns != self.displayed_columns:
4885
+ self.purge_undo_and_redo_stack()
4882
4886
  self.displayed_columns = sorted(columns)
4883
- if all_columns_displayed:
4884
- if not self.all_columns_displayed:
4885
- total_data_cols = self.total_data_cols()
4886
- self.displayed_columns = list(range(total_data_cols))
4887
- self.all_columns_displayed = True
4888
- elif all_columns_displayed is not None and not all_columns_displayed:
4889
- self.all_columns_displayed = False
4887
+ # setting all_columns_displayed
4888
+ if all_columns_displayed is not None:
4889
+ # setting it to True and it's currently False
4890
+ if all_columns_displayed and not self.all_columns_displayed:
4891
+ self.purge_undo_and_redo_stack()
4892
+ self.all_columns_displayed = True
4893
+ # setting it to False and it's currently True
4894
+ elif not all_columns_displayed and self.all_columns_displayed:
4895
+ # if columns is None then displayed_columns needs to be reset
4896
+ if columns is None:
4897
+ self.displayed_columns = list(range(self.total_data_cols()))
4898
+ self.all_columns_displayed = False
4890
4899
  if reset_col_positions:
4891
- self.reset_col_positions(ncols=total_data_cols)
4900
+ self.reset_col_positions()
4892
4901
  if deselect_all:
4893
4902
  self.deselect("all", redraw=False)
4894
4903
 
@@ -5245,21 +5254,21 @@ class MainTable(tk.Canvas):
5245
5254
  if open_:
5246
5255
  # up arrow
5247
5256
  points = (
5248
- x2 - 3 - small_mod - small_mod - small_mod - small_mod,
5257
+ x2 - 4 - small_mod - small_mod - small_mod - small_mod,
5249
5258
  y1 + mid_y + small_mod,
5250
- x2 - 3 - small_mod - small_mod,
5259
+ x2 - 4 - small_mod - small_mod,
5251
5260
  y1 + mid_y - small_mod,
5252
- x2 - 3,
5261
+ x2 - 4,
5253
5262
  y1 + mid_y + small_mod,
5254
5263
  )
5255
5264
  else:
5256
5265
  # down arrow
5257
5266
  points = (
5258
- x2 - 3 - small_mod - small_mod - small_mod - small_mod,
5267
+ x2 - 4 - small_mod - small_mod - small_mod - small_mod,
5259
5268
  y1 + mid_y - small_mod,
5260
- x2 - 3 - small_mod - small_mod,
5269
+ x2 - 4 - small_mod - small_mod,
5261
5270
  y1 + mid_y + small_mod,
5262
- x2 - 3,
5271
+ x2 - 4,
5263
5272
  y1 + mid_y - small_mod,
5264
5273
  )
5265
5274
  if self.hidd_dropdown:
@@ -5271,10 +5280,13 @@ class MainTable(tk.Canvas):
5271
5280
  self.itemconfig(t, fill=fill, tag=tag, state="normal")
5272
5281
  self.lift(t)
5273
5282
  else:
5274
- t = self.create_polygon(
5283
+ t = self.create_line(
5275
5284
  points,
5276
5285
  fill=fill,
5277
5286
  tag=tag,
5287
+ width=2,
5288
+ capstyle=tk.ROUND,
5289
+ joinstyle=tk.BEVEL,
5278
5290
  )
5279
5291
  self.disp_dropdown[t] = True
5280
5292
 
@@ -5443,7 +5455,7 @@ class MainTable(tk.Canvas):
5443
5455
  if self.PAR.ops.auto_resize_row_index and redraw_row_index and self.show_index:
5444
5456
  changed_w = self.RI.auto_set_index_width(
5445
5457
  end_row=grid_end_row,
5446
- only_rows=[self.datarn(r) for r in range(text_start_row, text_end_row)],
5458
+ only_rows=map(self.datarn, range(text_start_row, text_end_row)),
5447
5459
  )
5448
5460
  if resized_cols or resized_rows or changed_w:
5449
5461
  self.recreate_all_selection_boxes()
@@ -5957,7 +5969,7 @@ class MainTable(tk.Canvas):
5957
5969
  if not self.PAR.ops.rounded_boxes or not x2 - x1 or not y2 - y1:
5958
5970
  radius = 0
5959
5971
  else:
5960
- radius = 8
5972
+ radius = 5
5961
5973
  coords = rounded_box_coords(
5962
5974
  x1,
5963
5975
  y1,
@@ -6182,7 +6194,7 @@ class MainTable(tk.Canvas):
6182
6194
  x1, y1, x2, y2 = self.box_coords_x_canvas_coords(r1, c1, r2, c2, type_)
6183
6195
  self.display_box(x1, y1, x2, y2, fill=mt_bg, outline="", state=state, tags=type_, width=1, iid=fill_iid)
6184
6196
  self.RI.display_box(
6185
- 1,
6197
+ 0,
6186
6198
  y1,
6187
6199
  self.RI.current_width - 1,
6188
6200
  y2,
@@ -6558,8 +6570,7 @@ class MainTable(tk.Canvas):
6558
6570
  if self.text_editor.open and (r, c) == self.text_editor.coords:
6559
6571
  self.text_editor.window.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
6560
6572
  return
6561
- if self.text_editor.open:
6562
- self.hide_text_editor()
6573
+ self.hide_text_editor()
6563
6574
  if not self.see(r=r, c=c, check_cell_visibility=True):
6564
6575
  self.refresh()
6565
6576
  x = self.col_positions[c]
@@ -6693,14 +6704,12 @@ class MainTable(tk.Canvas):
6693
6704
  )
6694
6705
  # self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
6695
6706
 
6696
- def hide_text_editor(self, reason: None | str = None) -> None:
6707
+ def hide_text_editor(self) -> None:
6697
6708
  if self.text_editor.open:
6698
6709
  for binding in text_editor_to_unbind:
6699
6710
  self.text_editor.tktext.unbind(binding)
6700
6711
  self.itemconfig(self.text_editor.canvas_id, state="hidden")
6701
6712
  self.text_editor.open = False
6702
- if reason == "Escape":
6703
- self.focus_set()
6704
6713
 
6705
6714
  def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
6706
6715
  # checking if text editor should be closed or not
@@ -6718,6 +6727,7 @@ class MainTable(tk.Canvas):
6718
6727
  return "break"
6719
6728
  if event.keysym == "Escape":
6720
6729
  self.hide_text_editor_and_dropdown()
6730
+ self.focus_set()
6721
6731
  return
6722
6732
  # setting cell data with text editor value
6723
6733
  text_editor_value = self.text_editor.get()
@@ -6930,7 +6940,7 @@ class MainTable(tk.Canvas):
6930
6940
  c: int,
6931
6941
  event: object = None,
6932
6942
  ) -> None:
6933
- self.hide_text_editor("Escape")
6943
+ self.hide_text_editor()
6934
6944
  datarn = self.datarn(r)
6935
6945
  datacn = self.datacn(c)
6936
6946
  kwargs = self.get_cell_kwargs(datarn, datacn, key="dropdown")
@@ -7005,7 +7015,8 @@ class MainTable(tk.Canvas):
7005
7015
  else:
7006
7016
  self.update_idletasks()
7007
7017
  self.dropdown.window.bind("<FocusOut>", lambda _: self.close_dropdown_window(r, c))
7008
- self.dropdown.window.focus()
7018
+ self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
7019
+ self.dropdown.window.focus_set()
7009
7020
  redraw = True
7010
7021
  self.dropdown.open = True
7011
7022
  if redraw:
@@ -7061,12 +7072,12 @@ class MainTable(tk.Canvas):
7061
7072
  )
7062
7073
  if edited:
7063
7074
  try_binding(self.extra_end_edit_cell_func, event_data)
7064
- self.focus_set()
7065
7075
  self.recreate_all_selection_boxes()
7076
+ self.focus_set()
7066
7077
  self.hide_text_editor_and_dropdown(redraw=redraw)
7067
7078
 
7068
7079
  def hide_text_editor_and_dropdown(self, redraw: bool = True) -> None:
7069
- self.hide_text_editor("Escape")
7080
+ self.hide_text_editor()
7070
7081
  self.hide_dropdown_window()
7071
7082
  if redraw:
7072
7083
  self.refresh()
@@ -358,7 +358,16 @@ class RowIndex(tk.Canvas):
358
358
  self.MT.current_cursor = "sb_v_double_arrow"
359
359
  else:
360
360
  self.rsz_h = None
361
- if self.width_resizing_enabled and not mouse_over_resize:
361
+ if (
362
+ self.width_resizing_enabled
363
+ and not mouse_over_resize
364
+ and self.PAR.ops.auto_resize_row_index is not True
365
+ and not (
366
+ self.PAR.ops.auto_resize_row_index == "empty"
367
+ and not isinstance(self.MT._row_index, int)
368
+ and not self.MT._row_index
369
+ )
370
+ ):
362
371
  try:
363
372
  x1, y1, x2, y2 = (
364
373
  self.row_width_resize_bbox[0],
@@ -761,22 +770,18 @@ class RowIndex(tk.Canvas):
761
770
  self.MT.set_yviews("moveto", 1)
762
771
 
763
772
  def event_over_dropdown(self, r: int, datarn: int, event: object, canvasy: float) -> bool:
764
- if (
773
+ return (
765
774
  canvasy < self.MT.row_positions[r] + self.MT.index_txt_height
766
775
  and self.get_cell_kwargs(datarn, key="dropdown")
767
776
  and event.x > self.current_width - self.MT.index_txt_height - 4
768
- ):
769
- return True
770
- return False
777
+ )
771
778
 
772
779
  def event_over_checkbox(self, r: int, datarn: int, event: object, canvasy: float) -> bool:
773
- if (
780
+ return (
774
781
  canvasy < self.MT.row_positions[r] + self.MT.index_txt_height
775
782
  and self.get_cell_kwargs(datarn, key="checkbox")
776
783
  and event.x < self.MT.index_txt_height + 4
777
- ):
778
- return True
779
- return False
784
+ )
780
785
 
781
786
  def b1_release(self, event: object) -> None:
782
787
  if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
@@ -957,7 +962,7 @@ class RowIndex(tk.Canvas):
957
962
  run_binding_func: bool = True,
958
963
  ext: bool = False,
959
964
  ) -> int:
960
- boxes_to_hide = tuple(iid for iid in self.MT.selection_boxes)
965
+ boxes_to_hide = tuple(self.MT.selection_boxes)
961
966
  fill_iid = self.MT.create_selection_box(r, 0, r + 1, len(self.MT.col_positions) - 1, "rows", ext=ext)
962
967
  for iid in boxes_to_hide:
963
968
  self.MT.hide_selection_box(iid)
@@ -1000,7 +1005,7 @@ class RowIndex(tk.Canvas):
1000
1005
  y1,
1001
1006
  x2,
1002
1007
  y2,
1003
- radius=8 if self.PAR.ops.rounded_boxes else 0,
1008
+ radius=5 if self.PAR.ops.rounded_boxes else 0,
1004
1009
  )
1005
1010
  if isinstance(iid, int):
1006
1011
  self.coords(iid, coords)
@@ -1353,11 +1358,9 @@ class RowIndex(tk.Canvas):
1353
1358
  # the left hand downward point
1354
1359
  x1 + 5 + indent,
1355
1360
  y1 + mid_y + small_mod,
1356
-
1357
1361
  # the middle upward point
1358
1362
  x1 + 5 + indent + small_mod + small_mod,
1359
1363
  y1 + mid_y - small_mod,
1360
-
1361
1364
  # the right hand downward point
1362
1365
  x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
1363
1366
  y1 + mid_y + small_mod,
@@ -1368,11 +1371,9 @@ class RowIndex(tk.Canvas):
1368
1371
  # the upper point
1369
1372
  x1 + 5 + indent + small_mod + small_mod,
1370
1373
  y1 + mid_y - small_mod - small_mod,
1371
-
1372
1374
  # the middle point
1373
1375
  x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
1374
1376
  y1 + mid_y,
1375
-
1376
1377
  # the bottom point
1377
1378
  x1 + 5 + indent + small_mod + small_mod,
1378
1379
  y1 + mid_y + small_mod + small_mod,
@@ -1418,21 +1419,21 @@ class RowIndex(tk.Canvas):
1418
1419
  if open_:
1419
1420
  # up arrow
1420
1421
  points = (
1421
- x2 - 3 - small_mod - small_mod - small_mod - small_mod,
1422
+ x2 - 4 - small_mod - small_mod - small_mod - small_mod,
1422
1423
  y1 + mid_y + small_mod,
1423
- x2 - 3 - small_mod - small_mod,
1424
+ x2 - 4 - small_mod - small_mod,
1424
1425
  y1 + mid_y - small_mod,
1425
- x2 - 3,
1426
+ x2 - 4,
1426
1427
  y1 + mid_y + small_mod,
1427
1428
  )
1428
1429
  else:
1429
1430
  # down arrow
1430
1431
  points = (
1431
- x2 - 3 - small_mod - small_mod - small_mod - small_mod,
1432
+ x2 - 4 - small_mod - small_mod - small_mod - small_mod,
1432
1433
  y1 + mid_y - small_mod,
1433
- x2 - 3 - small_mod - small_mod,
1434
+ x2 - 4 - small_mod - small_mod,
1434
1435
  y1 + mid_y + small_mod,
1435
- x2 - 3,
1436
+ x2 - 4,
1436
1437
  y1 + mid_y - small_mod,
1437
1438
  )
1438
1439
  if self.hidd_dropdown:
@@ -1444,10 +1445,13 @@ class RowIndex(tk.Canvas):
1444
1445
  self.itemconfig(t, fill=fill, tag=tag, state="normal")
1445
1446
  self.lift(t)
1446
1447
  else:
1447
- t = self.create_polygon(
1448
+ t = self.create_line(
1448
1449
  points,
1449
1450
  fill=fill,
1450
1451
  tag=tag,
1452
+ width=2,
1453
+ capstyle=tk.ROUND,
1454
+ joinstyle=tk.BEVEL,
1451
1455
  )
1452
1456
  self.disp_dropdown[t] = True
1453
1457
 
@@ -1892,8 +1896,7 @@ class RowIndex(tk.Canvas):
1892
1896
  if self.text_editor.open and r == self.text_editor.row:
1893
1897
  self.text_editor.set_text(self.text_editor.get() + "" if not isinstance(text, str) else text)
1894
1898
  return
1895
- if self.text_editor.open:
1896
- self.hide_text_editor()
1899
+ self.hide_text_editor()
1897
1900
  if not self.MT.see(r=r, c=0, keep_yscroll=True, check_cell_visibility=True):
1898
1901
  self.MT.refresh()
1899
1902
  x = 0
@@ -2026,14 +2029,12 @@ class RowIndex(tk.Canvas):
2026
2029
  )
2027
2030
  # self.itemconfig(self.dropdown.canvas_id, anchor=anchor, height=win_h)
2028
2031
 
2029
- def hide_text_editor(self, reason: None | str = None) -> None:
2032
+ def hide_text_editor(self) -> None:
2030
2033
  if self.text_editor.open:
2031
2034
  for binding in text_editor_to_unbind:
2032
2035
  self.text_editor.tktext.unbind(binding)
2033
2036
  self.itemconfig(self.text_editor.canvas_id, state="hidden")
2034
2037
  self.text_editor.open = False
2035
- if reason == "Escape":
2036
- self.focus_set()
2037
2038
 
2038
2039
  # r is displayed row
2039
2040
  def close_text_editor(self, event: tk.Event) -> Literal["break"] | None:
@@ -2052,6 +2053,7 @@ class RowIndex(tk.Canvas):
2052
2053
  return "break"
2053
2054
  if event.keysym == "Escape":
2054
2055
  self.hide_text_editor_and_dropdown()
2056
+ self.focus_set()
2055
2057
  return
2056
2058
  text_editor_value = self.text_editor.get()
2057
2059
  r = self.text_editor.row
@@ -2133,7 +2135,7 @@ class RowIndex(tk.Canvas):
2133
2135
 
2134
2136
  # r is displayed row
2135
2137
  def open_dropdown_window(self, r: int, event: object = None) -> None:
2136
- self.hide_text_editor("Escape")
2138
+ self.hide_text_editor()
2137
2139
  kwargs = self.get_cell_kwargs(self.MT.datarn(r), key="dropdown")
2138
2140
  if kwargs["state"] == "normal":
2139
2141
  if not self.open_text_editor(event=event, r=r, dropdown=True):
@@ -2204,8 +2206,9 @@ class RowIndex(tk.Canvas):
2204
2206
  return
2205
2207
  redraw = False
2206
2208
  else:
2207
- self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(r))
2208
2209
  self.update_idletasks()
2210
+ self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(r))
2211
+ self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
2209
2212
  self.dropdown.window.focus_set()
2210
2213
  redraw = True
2211
2214
  self.dropdown.open = True
@@ -2246,12 +2249,12 @@ class RowIndex(tk.Canvas):
2246
2249
  edited = self.set_cell_data_undo(r, datarn=datarn, value=selection, redraw=not redraw)
2247
2250
  if edited:
2248
2251
  try_binding(self.extra_end_edit_cell_func, event_data)
2249
- self.focus_set()
2250
2252
  self.MT.recreate_all_selection_boxes()
2253
+ self.focus_set()
2251
2254
  self.hide_text_editor_and_dropdown(redraw=redraw)
2252
2255
 
2253
2256
  def hide_text_editor_and_dropdown(self, redraw: bool = True) -> None:
2254
- self.hide_text_editor("Escape")
2257
+ self.hide_text_editor()
2255
2258
  self.hide_dropdown_window()
2256
2259
  if redraw:
2257
2260
  self.MT.refresh()
@@ -2521,7 +2524,7 @@ class RowIndex(tk.Canvas):
2521
2524
  if not node.parent.children:
2522
2525
  self.tree_open_ids.discard(node.parent)
2523
2526
 
2524
- def pid_causes_recursive_loop(self, iid: str, pid: str) -> bool:
2527
+ def build_pid_causes_recursive_loop(self, iid: str, pid: str) -> bool:
2525
2528
  return any(
2526
2529
  i == pid
2527
2530
  for i in chain(
@@ -2529,3 +2532,8 @@ class RowIndex(tk.Canvas):
2529
2532
  islice(self.get_iid_ancestors(iid), 1, None),
2530
2533
  )
2531
2534
  )
2535
+
2536
+ def move_pid_causes_recursive_loop(self, to_move_iid: str, move_to_parent: str) -> bool:
2537
+ # if the parent the item is being moved under is one of the item's descendants
2538
+ # then it is a recursive loop
2539
+ return any(move_to_parent == diid for diid in self.get_iid_descendants(to_move_iid))
@@ -10,7 +10,14 @@ from collections.abc import (
10
10
  Iterator,
11
11
  Sequence,
12
12
  )
13
- from itertools import accumulate, chain, islice, product, repeat
13
+ from itertools import (
14
+ accumulate,
15
+ chain,
16
+ filterfalse,
17
+ islice,
18
+ product,
19
+ repeat,
20
+ )
14
21
  from timeit import default_timer
15
22
  from tkinter import ttk
16
23
  from typing import Literal
@@ -3813,7 +3820,6 @@ class Sheet(tk.Frame):
3813
3820
  columns: None | Literal["all"] | Iterator[int] = None,
3814
3821
  all_columns_displayed: None | bool = None,
3815
3822
  reset_col_positions: bool = True,
3816
- refresh: bool = False,
3817
3823
  redraw: bool = False,
3818
3824
  deselect_all: bool = True,
3819
3825
  **kwargs,
@@ -3828,8 +3834,9 @@ class Sheet(tk.Frame):
3828
3834
  reset_col_positions=reset_col_positions,
3829
3835
  deselect_all=deselect_all,
3830
3836
  )
3831
- if refresh or redraw:
3832
- self.set_refresh_timer(redraw if redraw else refresh)
3837
+ if "refresh" in kwargs:
3838
+ redraw = kwargs["refresh"]
3839
+ self.set_refresh_timer(redraw)
3833
3840
  return res
3834
3841
 
3835
3842
  def hide_columns(
@@ -3846,7 +3853,7 @@ class Sheet(tk.Frame):
3846
3853
  if not columns:
3847
3854
  return
3848
3855
  if self.MT.all_columns_displayed:
3849
- self.MT.displayed_columns = [c for c in range(self.MT.total_data_cols()) if c not in columns]
3856
+ self.MT.displayed_columns = list(filterfalse(columns.__contains__, range(self.MT.total_data_cols())))
3850
3857
  to_pop = {c: c for c in columns}
3851
3858
  else:
3852
3859
  to_pop = {}
@@ -3876,13 +3883,18 @@ class Sheet(tk.Frame):
3876
3883
  self.MT.deselect(redraw=False)
3877
3884
  return self.set_refresh_timer(redraw)
3878
3885
 
3879
- # uses data indexes
3880
3886
  def show_columns(
3881
3887
  self,
3882
3888
  columns: int | Iterator[int],
3883
3889
  redraw: bool = True,
3884
3890
  deselect_all: bool = True,
3885
3891
  ) -> Sheet:
3892
+ """
3893
+ 'columns' argument must be data indexes
3894
+ Function will return without action if Sheet.all_columns
3895
+ """
3896
+ if self.MT.all_columns_displayed:
3897
+ return
3886
3898
  if isinstance(columns, int):
3887
3899
  columns = [columns]
3888
3900
  cws = self.MT.get_column_widths()
@@ -3908,7 +3920,10 @@ class Sheet(tk.Frame):
3908
3920
 
3909
3921
  @all_columns.setter
3910
3922
  def all_columns(self, a: bool) -> Sheet:
3911
- self.MT.all_columns_displayed = a
3923
+ self.MT.display_columns(
3924
+ columns=None,
3925
+ all_columns_displayed=a,
3926
+ )
3912
3927
  return self
3913
3928
 
3914
3929
  @property
@@ -3917,8 +3932,8 @@ class Sheet(tk.Frame):
3917
3932
 
3918
3933
  @displayed_columns.setter
3919
3934
  def displayed_columns(self, columns: list[int]) -> Sheet:
3920
- self.display_columns(columns=columns, reset_col_positions=False, redraw=True)
3921
- return self
3935
+ self.display_columns(columns=columns, reset_col_positions=True, redraw=False)
3936
+ return self.set_refresh_timer()
3922
3937
 
3923
3938
  # Hiding Rows
3924
3939
 
@@ -3933,7 +3948,6 @@ class Sheet(tk.Frame):
3933
3948
  rows: None | Literal["all"] | Iterator[int] = None,
3934
3949
  all_rows_displayed: None | bool = None,
3935
3950
  reset_row_positions: bool = True,
3936
- refresh: bool = False,
3937
3951
  redraw: bool = False,
3938
3952
  deselect_all: bool = True,
3939
3953
  **kwargs,
@@ -3946,8 +3960,9 @@ class Sheet(tk.Frame):
3946
3960
  reset_row_positions=reset_row_positions,
3947
3961
  deselect_all=deselect_all,
3948
3962
  )
3949
- if refresh or redraw:
3950
- self.set_refresh_timer(redraw if redraw else refresh)
3963
+ if "refresh" in kwargs:
3964
+ redraw = kwargs["refresh"]
3965
+ self.set_refresh_timer(redraw)
3951
3966
  return res
3952
3967
 
3953
3968
  def hide_rows(
@@ -3965,7 +3980,7 @@ class Sheet(tk.Frame):
3965
3980
  if not rows:
3966
3981
  return
3967
3982
  if self.MT.all_rows_displayed:
3968
- self.MT.displayed_rows = [r for r in range(self.MT.total_data_rows()) if r not in rows]
3983
+ self.MT.displayed_rows = list(filterfalse(rows.__contains__, range(self.MT.total_data_rows())))
3969
3984
  to_pop = {r: r for r in rows}
3970
3985
  else:
3971
3986
  to_pop = {}
@@ -3996,13 +4011,18 @@ class Sheet(tk.Frame):
3996
4011
  self.MT.deselect(redraw=False)
3997
4012
  return self.set_refresh_timer(redraw)
3998
4013
 
3999
- # uses data indexes
4000
4014
  def show_rows(
4001
4015
  self,
4002
4016
  rows: int | Iterator[int],
4003
4017
  redraw: bool = True,
4004
4018
  deselect_all: bool = True,
4005
4019
  ) -> Sheet:
4020
+ """
4021
+ 'rows' argument must be data indexes
4022
+ Function will return without action if Sheet.all_rows
4023
+ """
4024
+ if self.MT.all_rows_displayed:
4025
+ return
4006
4026
  if isinstance(rows, int):
4007
4027
  rows = [rows]
4008
4028
  rhs = self.MT.get_row_heights()
@@ -4028,7 +4048,10 @@ class Sheet(tk.Frame):
4028
4048
 
4029
4049
  @all_rows.setter
4030
4050
  def all_rows(self, a: bool) -> Sheet:
4031
- self.MT.all_rows_displayed = a
4051
+ self.MT.display_rows(
4052
+ rows=None,
4053
+ all_rows_displayed=a,
4054
+ )
4032
4055
  return self
4033
4056
 
4034
4057
  @property
@@ -4037,8 +4060,8 @@ class Sheet(tk.Frame):
4037
4060
 
4038
4061
  @displayed_rows.setter
4039
4062
  def displayed_rows(self, rows: list[int]) -> Sheet:
4040
- self.display_rows(rows=rows, reset_row_positions=False, redraw=True)
4041
- return self
4063
+ self.display_rows(rows=rows, reset_row_positions=True, redraw=False)
4064
+ return self.set_refresh_timer()
4042
4065
 
4043
4066
  # Hiding Sheet Elements
4044
4067
 
@@ -4688,7 +4711,7 @@ class Sheet(tk.Frame):
4688
4711
  self.RI.tree[iid].text = row[text_column]
4689
4712
  else:
4690
4713
  self.RI.tree[iid] = Node(row[text_column], iid, "")
4691
- if safety and (iid == pid or self.RI.pid_causes_recursive_loop(iid, pid)):
4714
+ if safety and (iid == pid or self.RI.build_pid_causes_recursive_loop(iid, pid)):
4692
4715
  row[parent_column] = ""
4693
4716
  pid = ""
4694
4717
  if pid:
@@ -4747,7 +4770,7 @@ class Sheet(tk.Frame):
4747
4770
  Closes everything else
4748
4771
  """
4749
4772
  self.hide_rows(
4750
- set(rn for rn in self.MT.displayed_rows if self.MT._row_index[rn].parent),
4773
+ rows={rn for rn in self.MT.displayed_rows if self.MT._row_index[rn].parent},
4751
4774
  redraw=False,
4752
4775
  deselect_all=False,
4753
4776
  data_indexes=True,
@@ -4768,13 +4791,15 @@ class Sheet(tk.Frame):
4768
4791
  """
4769
4792
  to_open = []
4770
4793
  disp_set = set(self.MT.displayed_rows)
4771
- quick_rns = self.RI.tree_rns
4772
- quick_open_ids = self.RI.tree_open_ids
4794
+ tree = self.RI.tree
4795
+ rns = self.RI.tree_rns
4796
+ open_ids = self.RI.tree_open_ids
4797
+ descendants = self.RI.get_iid_descendants
4773
4798
  for item in filter(items.__contains__, self.get_children()):
4774
- if self.RI.tree[item].children:
4775
- quick_open_ids.add(item)
4776
- if quick_rns[item] in disp_set:
4777
- to_disp = [quick_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True)]
4799
+ if tree[item].children:
4800
+ open_ids.add(item)
4801
+ if rns[item] in disp_set:
4802
+ to_disp = [rns[did] for did in descendants(item, check_open=True)]
4778
4803
  for i in to_disp:
4779
4804
  disp_set.add(i)
4780
4805
  to_open.extend(to_disp)
@@ -4921,7 +4946,7 @@ class Sheet(tk.Frame):
4921
4946
  self.RI.tree_open_ids.add(item)
4922
4947
  if self.item_displayed(item):
4923
4948
  self.show_rows(
4924
- rows=(self.RI.tree_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True)),
4949
+ rows=map(self.RI.tree_rns.__getitem__, self.RI.get_iid_descendants(item, check_open=True)),
4925
4950
  redraw=False,
4926
4951
  deselect_all=False,
4927
4952
  )
@@ -4929,7 +4954,9 @@ class Sheet(tk.Frame):
4929
4954
  self.RI.tree_open_ids.discard(item)
4930
4955
  if self.item_displayed(item):
4931
4956
  self.hide_rows(
4932
- rows={self.RI.tree_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True)},
4957
+ rows=set(
4958
+ map(self.RI.tree_rns.__getitem__, self.RI.get_iid_descendants(item, check_open=True))
4959
+ ),
4933
4960
  redraw=False,
4934
4961
  deselect_all=False,
4935
4962
  data_indexes=True,
@@ -5014,7 +5041,8 @@ class Sheet(tk.Frame):
5014
5041
  def move(self, item: str, parent: str, index: int | None = None) -> Sheet:
5015
5042
  """
5016
5043
  Moves item to be under parent as child at index
5017
- 'parent' can be empty string which will make item a top node
5044
+ 'parent' can be an empty str which will put the item at top level
5045
+ Performance is not great
5018
5046
  """
5019
5047
  if (item := item.lower()) and item not in self.RI.tree:
5020
5048
  raise ValueError(f"Item '{item}' does not exist.")
@@ -5023,25 +5051,61 @@ class Sheet(tk.Frame):
5023
5051
  mapping = {}
5024
5052
  to_show = []
5025
5053
  item_node = self.RI.tree[item]
5054
+ item_r = self.RI.tree_rns[item]
5026
5055
  if parent:
5027
- if self.RI.pid_causes_recursive_loop(item, parent):
5056
+ if self.RI.move_pid_causes_recursive_loop(item, parent):
5028
5057
  raise ValueError(f"iid '{item}' causes a recursive loop with parent '{parent}'.")
5029
5058
  parent_node = self.RI.tree[parent]
5030
5059
  if parent_node.children:
5031
5060
  if index is None or index >= len(parent_node.children):
5032
- index = len(parent_node.children) - 1
5033
- item_r = self.RI.tree_rns[item]
5034
- new_r = self.RI.tree_rns[parent_node.children[index].iid]
5035
- new_r_desc = sum(1 for _ in self.RI.get_iid_descendants(parent_node.children[index].iid))
5036
- item_desc = sum(1 for _ in self.RI.get_iid_descendants(item))
5037
- if item_r < new_r:
5038
- r_ctr = new_r + new_r_desc - item_desc
5061
+ index = len(parent_node.children)
5062
+ new_r = self.RI.tree_rns[parent] + sum(1 for _ in self.RI.get_iid_descendants(parent))
5063
+ # new parent has children
5064
+ # index is on end
5065
+ # item row is less than move to row
5066
+ if item_r < new_r:
5067
+ r_ctr = new_r - sum(1 for _ in self.RI.get_iid_descendants(item))
5068
+
5069
+ # new parent has children
5070
+ # index is on end
5071
+ # item row is greater than move to row
5072
+ else:
5073
+ r_ctr = new_r + 1
5039
5074
  else:
5040
- r_ctr = new_r
5075
+ new_r = self.RI.tree_rns[parent_node.children[index].iid]
5076
+ # new parent has children
5077
+ # index is not end
5078
+ # item row is less than move to row
5079
+ if item_r < new_r:
5080
+ if self.RI.items_parent(item) == parent:
5081
+ r_ctr = (
5082
+ new_r
5083
+ + sum(1 for _ in self.RI.get_iid_descendants(parent_node.children[index].iid))
5084
+ - sum(1 for _ in self.RI.get_iid_descendants(item))
5085
+ )
5086
+ else:
5087
+ r_ctr = new_r - sum(1 for _ in self.RI.get_iid_descendants(item)) - 1
5088
+
5089
+ # new parent has children
5090
+ # index is not end
5091
+ # item row is greater than move to row
5092
+ else:
5093
+ r_ctr = new_r
5041
5094
  else:
5042
- if index is None:
5043
- index = 0
5044
- r_ctr = self.RI.tree_rns[parent_node.iid] + 1
5095
+ index = 0
5096
+ new_r = self.RI.tree_rns[parent_node.iid]
5097
+
5098
+ # new parent doesn't have children
5099
+ # index always start
5100
+ # item row is less than move to row
5101
+ if item_r < new_r:
5102
+ r_ctr = new_r - sum(1 for _ in self.RI.get_iid_descendants(item))
5103
+
5104
+ # new parent doesn't have children
5105
+ # index always start
5106
+ # item row is greater than move to row
5107
+ else:
5108
+ r_ctr = new_r + 1
5045
5109
  mapping[item_r] = r_ctr
5046
5110
  if parent in self.RI.tree_open_ids and self.item_displayed(parent):
5047
5111
  to_show.append(r_ctr)
@@ -5064,11 +5128,12 @@ class Sheet(tk.Frame):
5064
5128
  else:
5065
5129
  if (new_r := self.top_index_row(index)) is None:
5066
5130
  new_r = self.top_index_row((sum(1 for _ in self.RI.gen_top_nodes()) - 1))
5067
- item_r = self.RI.tree_rns[item]
5068
5131
  if item_r < new_r:
5069
- par_desc = sum(1 for _ in self.RI.get_iid_descendants(self.rowitem(new_r, data_index=True)))
5070
- item_desc = sum(1 for _ in self.RI.get_iid_descendants(item))
5071
- r_ctr = new_r + par_desc - item_desc
5132
+ r_ctr = (
5133
+ new_r
5134
+ + sum(1 for _ in self.RI.get_iid_descendants(self.rowitem(new_r, data_index=True)))
5135
+ - sum(1 for _ in self.RI.get_iid_descendants(item))
5136
+ )
5072
5137
  else:
5073
5138
  r_ctr = new_r
5074
5139
  mapping[item_r] = r_ctr
@@ -5106,7 +5171,8 @@ class Sheet(tk.Frame):
5106
5171
  if (item := item.lower()) not in self.RI.tree:
5107
5172
  raise ValueError(f"Item '{item}' does not exist.")
5108
5173
  if not self.RI.tree[item].parent:
5109
- return next(index for index, node in enumerate(self.RI.gen_top_nodes()) if node == self.RI.tree[item])
5174
+ find_node = self.RI.tree[item]
5175
+ return next(index for index, node in enumerate(self.RI.gen_top_nodes()) if node == find_node)
5110
5176
  return self.RI.tree[item].parent.children.index(self.RI.tree[item])
5111
5177
 
5112
5178
  def item_displayed(self, item: str) -> bool:
@@ -5128,8 +5194,11 @@ class Sheet(tk.Frame):
5128
5194
  if (item := item.lower()) not in self.RI.tree:
5129
5195
  raise ValueError(f"Item '{item}' does not exist.")
5130
5196
  if self.RI.tree[item].parent:
5131
- for iid in self.RI.get_iid_ancestors(item):
5132
- self.item(iid, open_=True, redraw=False)
5197
+ self.show_rows(
5198
+ rows=self._tree_open(list(self.RI.get_iid_ancestors(item))),
5199
+ redraw=False,
5200
+ deselect_all=False,
5201
+ )
5133
5202
  return self.set_refresh_timer(redraw)
5134
5203
 
5135
5204
  def scroll_to_item(self, item: str, redraw=False) -> Sheet:
@@ -5151,14 +5220,15 @@ class Sheet(tk.Frame):
5151
5220
  Get currently selected item ids
5152
5221
  """
5153
5222
  return [
5154
- self.MT._row_index[self.displayed_row_to_data(rn)].iid
5155
- for rn in self.get_selected_rows(get_cells_as_rows=cells)
5223
+ self.MT._row_index[self.MT.displayed_rows[rn]].iid for rn in self.get_selected_rows(get_cells_as_rows=cells)
5156
5224
  ]
5157
5225
 
5158
5226
  def selection_set(self, *items, redraw: bool = True) -> Sheet:
5159
5227
  if any(item.lower() in self.RI.tree for item in unpack(items)):
5160
- self.deselect(redraw=False)
5228
+ boxes_to_hide = tuple(self.MT.selection_boxes)
5161
5229
  self.selection_add(*items, redraw=False)
5230
+ for iid in boxes_to_hide:
5231
+ self.MT.hide_selection_box(iid)
5162
5232
  return self.set_refresh_timer(redraw)
5163
5233
 
5164
5234
  def selection_add(self, *items, redraw: bool = True) -> Sheet:
@@ -5220,7 +5290,7 @@ class Sheet(tk.Frame):
5220
5290
 
5221
5291
  # Functions not in docs
5222
5292
 
5223
- def event_generate(self, *args, **kwargs):
5293
+ def event_generate(self, *args, **kwargs) -> None:
5224
5294
  self.MT.event_generate(*args, **kwargs)
5225
5295
 
5226
5296
  def emit_event(
@@ -6226,13 +6296,7 @@ class Sheet(tk.Frame):
6226
6296
  ) -> Sheet:
6227
6297
  kwargs = get_dropdown_kwargs(*args, **kwargs)
6228
6298
  d = get_dropdown_dict(**kwargs)
6229
- if kwargs["set_value"] is None:
6230
- if kwargs["values"] and (v := self.MT.get_cell_data(r, c)) not in kwargs["values"]:
6231
- v = kwargs["values"][0]
6232
- else:
6233
- v == ""
6234
- else:
6235
- v = kwargs["set_value"]
6299
+ v = kwargs["set_value"] if kwargs["set_value"] is not None else kwargs["values"][0] if kwargs["values"] else ""
6236
6300
  if isinstance(r, str) and r.lower() == "all" and isinstance(c, int):
6237
6301
  for r_ in range(self.MT.total_data_rows()):
6238
6302
  self._create_dropdown(r_, c, v, d)
@@ -163,17 +163,16 @@ class TopLeftRectangle(tk.Canvas):
163
163
  recreate_selection_boxes: bool = True,
164
164
  ) -> None:
165
165
  try:
166
- self.update_idletasks()
167
- if new_h is None:
168
- h = self.winfo_height()
169
- if new_w is None:
170
- w = self.winfo_width()
171
- if new_w:
172
- self.config(width=new_w)
173
- w = new_w
174
- if new_h:
175
- self.config(height=new_h)
166
+ if isinstance(new_h, int):
176
167
  h = new_h
168
+ self.config(height=h)
169
+ else:
170
+ h = self.CH.current_height
171
+ if isinstance(new_w, int):
172
+ w = new_w
173
+ self.config(width=w)
174
+ else:
175
+ w = self.RI.current_width
177
176
  except Exception:
178
177
  return
179
178
  self.coords(self.rw_box, 0, h - 5, w, h)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tksheet
3
- Version: 7.2.8
3
+ Version: 7.2.10
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
File without changes
File without changes