tksheet 7.2.21__py3-none-any.whl → 7.2.23__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/row_index.py CHANGED
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import tkinter as tk
4
4
  from collections import defaultdict
5
5
  from collections.abc import (
6
- Callable,
7
6
  Generator,
8
7
  Hashable,
9
8
  Iterator,
@@ -809,19 +808,17 @@ class RowIndex(tk.Canvas):
809
808
  )
810
809
 
811
810
  def b1_release(self, event: object) -> None:
811
+ to_hide = self.being_drawn_item
812
812
  if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
813
813
  r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
814
- self.MT.hide_selection_box(self.being_drawn_item)
814
+ self.being_drawn_item = None
815
815
  self.MT.set_currently_selected(
816
816
  r_to_sel,
817
817
  c_to_sel,
818
818
  item=self.MT.create_selection_box(*to_sel, set_current=False),
819
+ run_binding=False,
819
820
  )
820
- sel_event = self.MT.get_select_event(being_drawn_item=self.being_drawn_item)
821
- try_binding(self.drag_selection_binding_func, sel_event)
822
- self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
823
- else:
824
- self.being_drawn_item = None
821
+ self.MT.hide_selection_box(to_hide)
825
822
  self.MT.bind("<MouseWheel>", self.MT.mousewheel)
826
823
  if self.height_resizing_enabled and self.rsz_h is not None and self.currently_resizing_height:
827
824
  self.drag_height_resize()
@@ -1222,27 +1219,28 @@ class RowIndex(tk.Canvas):
1222
1219
  fr: float,
1223
1220
  sr: float,
1224
1221
  r: int,
1225
- c_2: str,
1226
- c_3: str,
1222
+ sel_cells_bg: str,
1223
+ sel_rows_bg: str,
1227
1224
  selections: dict,
1228
1225
  datarn: int,
1229
1226
  ) -> tuple[str, str, bool]:
1230
1227
  redrawn = False
1231
1228
  kwargs = self.get_cell_kwargs(datarn, key="highlight")
1232
1229
  if kwargs:
1233
- if kwargs[0] is not None:
1234
- c_1 = kwargs[0] if kwargs[0].startswith("#") else color_map[kwargs[0]]
1230
+ fill = kwargs[0]
1231
+ if fill and not fill.startswith("#"):
1232
+ fill = color_map[fill]
1235
1233
  if "rows" in selections and r in selections["rows"]:
1236
1234
  txtfg = (
1237
1235
  self.PAR.ops.index_selected_rows_fg
1238
1236
  if kwargs[1] is None or self.PAR.ops.display_selected_fg_over_highlights
1239
1237
  else kwargs[1]
1240
1238
  )
1241
- if kwargs[0] is not None:
1239
+ if fill:
1242
1240
  fill = (
1243
- f"#{int((int(c_1[1:3], 16) + int(c_3[1:3], 16)) / 2):02X}"
1244
- + f"{int((int(c_1[3:5], 16) + int(c_3[3:5], 16)) / 2):02X}"
1245
- + f"{int((int(c_1[5:], 16) + int(c_3[5:], 16)) / 2):02X}"
1241
+ f"#{int((int(fill[1:3], 16) + int(sel_rows_bg[1:3], 16)) / 2):02X}"
1242
+ + f"{int((int(fill[3:5], 16) + int(sel_rows_bg[3:5], 16)) / 2):02X}"
1243
+ + f"{int((int(fill[5:], 16) + int(sel_rows_bg[5:], 16)) / 2):02X}"
1246
1244
  )
1247
1245
  elif "cells" in selections and r in selections["cells"]:
1248
1246
  txtfg = (
@@ -1250,17 +1248,15 @@ class RowIndex(tk.Canvas):
1250
1248
  if kwargs[1] is None or self.PAR.ops.display_selected_fg_over_highlights
1251
1249
  else kwargs[1]
1252
1250
  )
1253
- if kwargs[0] is not None:
1251
+ if fill:
1254
1252
  fill = (
1255
- f"#{int((int(c_1[1:3], 16) + int(c_2[1:3], 16)) / 2):02X}"
1256
- + f"{int((int(c_1[3:5], 16) + int(c_2[3:5], 16)) / 2):02X}"
1257
- + f"{int((int(c_1[5:], 16) + int(c_2[5:], 16)) / 2):02X}"
1253
+ f"#{int((int(fill[1:3], 16) + int(sel_cells_bg[1:3], 16)) / 2):02X}"
1254
+ + f"{int((int(fill[3:5], 16) + int(sel_cells_bg[3:5], 16)) / 2):02X}"
1255
+ + f"{int((int(fill[5:], 16) + int(sel_cells_bg[5:], 16)) / 2):02X}"
1258
1256
  )
1259
1257
  else:
1260
1258
  txtfg = self.PAR.ops.index_fg if kwargs[1] is None else kwargs[1]
1261
- if kwargs[0] is not None:
1262
- fill = kwargs[0]
1263
- if kwargs[0] is not None:
1259
+ if fill:
1264
1260
  redrawn = self.redraw_highlight(
1265
1261
  0,
1266
1262
  fr + 1,
@@ -1592,12 +1588,12 @@ class RowIndex(tk.Canvas):
1592
1588
  )
1593
1589
  )
1594
1590
  self.redraw_gridline(points=points, fill=self.PAR.ops.index_grid_fg, width=1, tag="h")
1595
- c_2 = (
1591
+ sel_cells_bg = (
1596
1592
  self.PAR.ops.index_selected_cells_bg
1597
1593
  if self.PAR.ops.index_selected_cells_bg.startswith("#")
1598
1594
  else color_map[self.PAR.ops.index_selected_cells_bg]
1599
1595
  )
1600
- c_3 = (
1596
+ sel_rows_bg = (
1601
1597
  self.PAR.ops.index_selected_rows_bg
1602
1598
  if self.PAR.ops.index_selected_rows_bg.startswith("#")
1603
1599
  else color_map[self.PAR.ops.index_selected_rows_bg]
@@ -1614,13 +1610,13 @@ class RowIndex(tk.Canvas):
1614
1610
  continue
1615
1611
  datarn = r if self.MT.all_rows_displayed else self.MT.displayed_rows[r]
1616
1612
  fill, tree_arrow_fg, dd_drawn = self.redraw_highlight_get_text_fg(
1617
- rtopgridln,
1618
- rbotgridln,
1619
- r,
1620
- c_2,
1621
- c_3,
1622
- selections,
1623
- datarn,
1613
+ fr=rtopgridln,
1614
+ sr=rbotgridln,
1615
+ r=r,
1616
+ sel_cells_bg=sel_cells_bg,
1617
+ sel_rows_bg=sel_rows_bg,
1618
+ selections=selections,
1619
+ datarn=datarn,
1624
1620
  )
1625
1621
 
1626
1622
  if datarn in self.cell_options and "align" in self.cell_options[datarn]:
@@ -1637,7 +1633,7 @@ class RowIndex(tk.Canvas):
1637
1633
  rtopgridln,
1638
1634
  self.current_width - 1,
1639
1635
  rbotgridln - 1,
1640
- fill=fill,
1636
+ fill=fill if dropdown_kwargs["state"] != "disabled" else self.PAR.ops.index_grid_fg,
1641
1637
  outline=fill,
1642
1638
  tag="dd",
1643
1639
  draw_outline=not dd_drawn,
@@ -1656,7 +1652,7 @@ class RowIndex(tk.Canvas):
1656
1652
  rtopgridln,
1657
1653
  self.current_width - 1,
1658
1654
  rbotgridln - 1,
1659
- fill=fill,
1655
+ fill=fill if dropdown_kwargs["state"] != "disabled" else self.PAR.ops.index_grid_fg,
1660
1656
  outline=fill,
1661
1657
  tag="dd",
1662
1658
  draw_outline=not dd_drawn,
@@ -1676,7 +1672,7 @@ class RowIndex(tk.Canvas):
1676
1672
  rtopgridln,
1677
1673
  self.current_width - 1,
1678
1674
  rbotgridln - 1,
1679
- fill=fill,
1675
+ fill=fill if dropdown_kwargs["state"] != "disabled" else self.PAR.ops.index_grid_fg,
1680
1676
  outline=fill,
1681
1677
  tag="dd",
1682
1678
  draw_outline=not dd_drawn,
@@ -1928,7 +1924,6 @@ class RowIndex(tk.Canvas):
1928
1924
  h = self.MT.row_positions[r + 1] - y + 1
1929
1925
  if text is None:
1930
1926
  text = self.get_cell_data(self.MT.datarn(r), none_to_empty_str=True, redirect_int=True)
1931
- bg, fg = self.PAR.ops.index_bg, self.PAR.ops.index_fg
1932
1927
  kwargs = {
1933
1928
  "menu_kwargs": DotDict(
1934
1929
  {
@@ -1946,8 +1941,10 @@ class RowIndex(tk.Canvas):
1946
1941
  "width": w,
1947
1942
  "height": h,
1948
1943
  "show_border": True,
1949
- "bg": bg,
1950
- "fg": fg,
1944
+ "bg": self.PAR.ops.index_editor_bg,
1945
+ "fg": self.PAR.ops.index_editor_fg,
1946
+ "select_bg": self.PAR.ops.index_editor_select_bg,
1947
+ "select_fg": self.PAR.ops.index_editor_select_fg,
1951
1948
  "align": self.get_cell_align(r),
1952
1949
  "r": r,
1953
1950
  }
@@ -2148,21 +2145,36 @@ class RowIndex(tk.Canvas):
2148
2145
 
2149
2146
  def dropdown_text_editor_modified(
2150
2147
  self,
2151
- dd_window: object,
2152
- event: dict,
2153
- modified_func: Callable | None,
2148
+ event: tk.Misc,
2154
2149
  ) -> None:
2155
- if modified_func:
2156
- modified_func(event)
2157
- dd_window.search_and_see(event)
2150
+ r = self.dropdown.get_coords()
2151
+ event_data = event_dict(
2152
+ name="table_dropdown_modified",
2153
+ sheet=self.PAR.name,
2154
+ value=self.text_editor.get(),
2155
+ loc=r,
2156
+ row=r,
2157
+ column=0,
2158
+ boxes=self.MT.get_boxes(),
2159
+ selected=self.MT.selected,
2160
+ )
2161
+ try_binding(self.dropdown.window.modified_function, event_data)
2162
+ # return to tk.Text action if control/command is held down
2163
+ # or keysym was not a character
2164
+ if (hasattr(event, "state") and event.state & (0x0004 | 0x00000010)) or (
2165
+ hasattr(event, "keysym") and len(event.keysym) > 2 and event.keysym != "space"
2166
+ ):
2167
+ return
2168
+ self.text_editor.autocomplete(self.dropdown.window.search_and_see(event_data))
2169
+ return "break"
2158
2170
 
2159
- # r is displayed row
2160
2171
  def open_dropdown_window(self, r: int, event: object = None) -> None:
2161
2172
  self.hide_text_editor()
2162
2173
  kwargs = self.get_cell_kwargs(self.MT.datarn(r), key="dropdown")
2163
- if kwargs["state"] == "normal":
2164
- if not self.open_text_editor(event=event, r=r, dropdown=True):
2165
- return
2174
+ if kwargs["state"] == "disabled":
2175
+ return
2176
+ if kwargs["state"] == "normal" and not self.open_text_editor(event=event, r=r, dropdown=True):
2177
+ return
2166
2178
  win_h, anchor = self.get_dropdown_height_anchor(r)
2167
2179
  win_w = self.current_width + 1
2168
2180
  if anchor == "nw":
@@ -2176,6 +2188,10 @@ class RowIndex(tk.Canvas):
2176
2188
  reset_kwargs = {
2177
2189
  "r": r,
2178
2190
  "c": 0,
2191
+ "bg": self.PAR.ops.index_editor_bg,
2192
+ "fg": self.PAR.ops.index_editor_fg,
2193
+ "select_bg": self.PAR.ops.index_editor_select_bg,
2194
+ "select_fg": self.PAR.ops.index_editor_select_fg,
2179
2195
  "width": win_w,
2180
2196
  "height": win_h,
2181
2197
  "font": self.PAR.ops.index_font,
@@ -2183,6 +2199,8 @@ class RowIndex(tk.Canvas):
2183
2199
  "outline_color": self.PAR.ops.index_selected_rows_bg,
2184
2200
  "align": self.get_cell_align(r),
2185
2201
  "values": kwargs["values"],
2202
+ "search_function": kwargs["search_function"],
2203
+ "modified_function": kwargs["modified_function"],
2186
2204
  }
2187
2205
  if self.dropdown.window:
2188
2206
  self.dropdown.window.reset(**reset_kwargs)
@@ -2195,7 +2213,6 @@ class RowIndex(tk.Canvas):
2195
2213
  **reset_kwargs,
2196
2214
  single_index="r",
2197
2215
  close_dropdown_window=self.close_dropdown_window,
2198
- search_function=kwargs["search_function"],
2199
2216
  arrowkey_RIGHT=self.MT.arrowkey_RIGHT,
2200
2217
  arrowkey_LEFT=self.MT.arrowkey_LEFT,
2201
2218
  )
@@ -2204,24 +2221,12 @@ class RowIndex(tk.Canvas):
2204
2221
  window=self.dropdown.window,
2205
2222
  anchor=anchor,
2206
2223
  )
2224
+ self.update_idletasks()
2207
2225
  if kwargs["state"] == "normal":
2208
2226
  self.text_editor.tktext.bind(
2209
- "<<TextModified>>",
2210
- lambda _x: self.dropdown_text_editor_modified(
2211
- self.dropdown.window,
2212
- event_dict(
2213
- name="index_dropdown_modified",
2214
- sheet=self.PAR.name,
2215
- value=self.text_editor.get(),
2216
- loc=r,
2217
- row=r,
2218
- boxes=self.MT.get_boxes(),
2219
- selected=self.MT.selected,
2220
- ),
2221
- kwargs["modified_function"],
2222
- ),
2227
+ "<KeyRelease>",
2228
+ self.dropdown_text_editor_modified,
2223
2229
  )
2224
- self.update_idletasks()
2225
2230
  try:
2226
2231
  self.after(1, lambda: self.text_editor.tktext.focus())
2227
2232
  self.after(2, self.text_editor.window.scroll_to_bottom())
@@ -2229,7 +2234,6 @@ class RowIndex(tk.Canvas):
2229
2234
  return
2230
2235
  redraw = False
2231
2236
  else:
2232
- self.update_idletasks()
2233
2237
  self.dropdown.window.bind("<FocusOut>", lambda _x: self.close_dropdown_window(r))
2234
2238
  self.dropdown.window.bind("<Escape>", self.close_dropdown_window)
2235
2239
  self.dropdown.window.focus_set()
tksheet/sheet.py CHANGED
@@ -200,8 +200,8 @@ class Sheet(tk.Frame):
200
200
  alternate_color: str = "",
201
201
  # colors
202
202
  outline_thickness: int = 0,
203
- outline_color: str = theme_light_blue["outline_color"],
204
203
  theme: str = "light blue",
204
+ outline_color: str = theme_light_blue["outline_color"],
205
205
  frame_bg: str = theme_light_blue["table_bg"],
206
206
  popup_menu_fg: str = theme_light_blue["popup_menu_fg"],
207
207
  popup_menu_bg: str = theme_light_blue["popup_menu_bg"],
@@ -210,6 +210,10 @@ class Sheet(tk.Frame):
210
210
  table_grid_fg: str = theme_light_blue["table_grid_fg"],
211
211
  table_bg: str = theme_light_blue["table_bg"],
212
212
  table_fg: str = theme_light_blue["table_fg"],
213
+ table_editor_bg: str = theme_light_blue["table_editor_bg"],
214
+ table_editor_fg: str = theme_light_blue["table_editor_fg"],
215
+ table_editor_select_bg: str = theme_light_blue["table_editor_select_bg"],
216
+ table_editor_select_fg: str = theme_light_blue["table_editor_select_fg"],
213
217
  table_selected_box_cells_fg: str = theme_light_blue["table_selected_box_cells_fg"],
214
218
  table_selected_box_rows_fg: str = theme_light_blue["table_selected_box_rows_fg"],
215
219
  table_selected_box_columns_fg: str = theme_light_blue["table_selected_box_columns_fg"],
@@ -228,6 +232,10 @@ class Sheet(tk.Frame):
228
232
  index_border_fg: str = theme_light_blue["index_border_fg"],
229
233
  index_grid_fg: str = theme_light_blue["index_grid_fg"],
230
234
  index_fg: str = theme_light_blue["index_fg"],
235
+ index_editor_bg: str = theme_light_blue["index_editor_bg"],
236
+ index_editor_fg: str = theme_light_blue["index_editor_fg"],
237
+ index_editor_select_bg: str = theme_light_blue["index_editor_select_bg"],
238
+ index_editor_select_fg: str = theme_light_blue["index_editor_select_fg"],
231
239
  index_selected_cells_bg: str = theme_light_blue["index_selected_cells_bg"],
232
240
  index_selected_cells_fg: str = theme_light_blue["index_selected_cells_fg"],
233
241
  index_selected_rows_bg: str = theme_light_blue["index_selected_rows_bg"],
@@ -237,6 +245,10 @@ class Sheet(tk.Frame):
237
245
  header_border_fg: str = theme_light_blue["header_border_fg"],
238
246
  header_grid_fg: str = theme_light_blue["header_grid_fg"],
239
247
  header_fg: str = theme_light_blue["header_fg"],
248
+ header_editor_bg: str = theme_light_blue["header_editor_bg"],
249
+ header_editor_fg: str = theme_light_blue["header_editor_fg"],
250
+ header_editor_select_bg: str = theme_light_blue["header_editor_select_bg"],
251
+ header_editor_select_fg: str = theme_light_blue["header_editor_select_fg"],
240
252
  header_selected_cells_bg: str = theme_light_blue["header_selected_cells_bg"],
241
253
  header_selected_cells_fg: str = theme_light_blue["header_selected_cells_fg"],
242
254
  header_selected_columns_bg: str = theme_light_blue["header_selected_columns_bg"],
@@ -259,10 +271,6 @@ class Sheet(tk.Frame):
259
271
  horizontal_scroll_troughrelief: str = theme_light_blue["horizontal_scroll_troughrelief"],
260
272
  vertical_scroll_bordercolor: str = theme_light_blue["vertical_scroll_bordercolor"],
261
273
  horizontal_scroll_bordercolor: str = theme_light_blue["horizontal_scroll_bordercolor"],
262
- vertical_scroll_borderwidth: int = 1,
263
- horizontal_scroll_borderwidth: int = 1,
264
- vertical_scroll_gripcount: int = 0,
265
- horizontal_scroll_gripcount: int = 0,
266
274
  vertical_scroll_active_bg: str = theme_light_blue["vertical_scroll_active_bg"],
267
275
  horizontal_scroll_active_bg: str = theme_light_blue["horizontal_scroll_active_bg"],
268
276
  vertical_scroll_not_active_bg: str = theme_light_blue["vertical_scroll_not_active_bg"],
@@ -275,6 +283,10 @@ class Sheet(tk.Frame):
275
283
  horizontal_scroll_not_active_fg: str = theme_light_blue["horizontal_scroll_not_active_fg"],
276
284
  vertical_scroll_pressed_fg: str = theme_light_blue["vertical_scroll_pressed_fg"],
277
285
  horizontal_scroll_pressed_fg: str = theme_light_blue["horizontal_scroll_pressed_fg"],
286
+ vertical_scroll_borderwidth: int = 1,
287
+ horizontal_scroll_borderwidth: int = 1,
288
+ vertical_scroll_gripcount: int = 0,
289
+ horizontal_scroll_gripcount: int = 0,
278
290
  scrollbar_theme_inheritance: str = "default",
279
291
  scrollbar_show_arrows: bool = True,
280
292
  # changing the arrowsize (width) of the scrollbars
@@ -607,6 +619,46 @@ class Sheet(tk.Frame):
607
619
  # Bindings and Functionality
608
620
 
609
621
  def enable_bindings(self, *bindings: str) -> Sheet:
622
+ """
623
+ List of available bindings:
624
+ - "all"
625
+ - "single_select"
626
+ - "toggle_select"
627
+ - "drag_select"
628
+ - "select_all"
629
+ - "column_drag_and_drop" / "move_columns"
630
+ - "row_drag_and_drop" / "move_rows"
631
+ - "column_select"
632
+ - "row_select"
633
+ - "column_width_resize"
634
+ - "double_click_column_resize"
635
+ - "row_width_resize"
636
+ - "column_height_resize"
637
+ - "arrowkeys" # all arrowkeys including page up and down
638
+ - "up"
639
+ - "down"
640
+ - "left"
641
+ - "right"
642
+ - "prior" # page up
643
+ - "next" # page down
644
+ - "row_height_resize"
645
+ - "double_click_row_resize"
646
+ - "right_click_popup_menu" / "rc_popup_menu" / "rc_menu"
647
+ - "rc_select"
648
+ - "rc_insert_column"
649
+ - "rc_delete_column"
650
+ - "rc_insert_row"
651
+ - "rc_delete_row"
652
+ - "ctrl_click_select" / "ctrl_select"
653
+ - "copy"
654
+ - "cut"
655
+ - "paste"
656
+ - "delete"
657
+ - "undo"
658
+ - "edit_cell"
659
+ - "edit_header"
660
+ - "edit_index"
661
+ """
610
662
  self.MT.enable_bindings(bindings)
611
663
  return self
612
664
 
@@ -619,6 +671,57 @@ class Sheet(tk.Frame):
619
671
  bindings: str | list | tuple | None = None,
620
672
  func: Callable | None = None,
621
673
  ) -> Sheet:
674
+ """
675
+ List of available bindings:
676
+ - "begin_copy", "begin_ctrl_c"
677
+ - "ctrl_c", "end_copy", "end_ctrl_c", "copy"
678
+ - "begin_cut", "begin_ctrl_x"
679
+ - "ctrl_x", "end_cut", "end_ctrl_x", "cut"
680
+ - "begin_paste", "begin_ctrl_v"
681
+ - "ctrl_v", "end_paste", "end_ctrl_v", "paste"
682
+ - "begin_undo", "begin_ctrl_z"
683
+ - "ctrl_z", "end_undo", "end_ctrl_z", "undo"
684
+ - "begin_delete_key", "begin_delete"
685
+ - "delete_key", "end_delete", "end_delete_key", "delete"
686
+ - "begin_edit_cell", "begin_edit_table"
687
+ - "end_edit_cell", "edit_cell", "edit_table"
688
+ - "begin_edit_header"
689
+ - "end_edit_header", "edit_header"
690
+ - "begin_edit_index"
691
+ - "end_edit_index", "edit_index"
692
+ - "begin_row_index_drag_drop", "begin_move_rows"
693
+ - "row_index_drag_drop", "move_rows", "end_move_rows", "end_row_index_drag_drop"
694
+ - "begin_column_header_drag_drop", "begin_move_columns"
695
+ - "column_header_drag_drop", "move_columns", "end_move_columns", "end_column_header_drag_drop"
696
+ - "begin_rc_delete_row", "begin_delete_rows"
697
+ - "rc_delete_row", "end_rc_delete_row", "end_delete_rows", "delete_rows"
698
+ - "begin_rc_delete_column", "begin_delete_columns"
699
+ - "rc_delete_column", "end_rc_delete_column","end_delete_columns", "delete_columns"
700
+ - "begin_rc_insert_column", "begin_insert_column", "begin_insert_columns", "begin_add_column","begin_rc_add_column", "begin_add_columns"
701
+ - "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column", "end_rc_add_column", "end_add_column", "end_add_columns"
702
+ - "begin_rc_insert_row", "begin_insert_row", "begin_insert_rows", "begin_rc_add_row", "begin_add_row", "begin_add_rows"
703
+ - "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row", "end_add_row", "end_add_rows"
704
+ - "row_height_resize"
705
+ - "column_width_resize"
706
+ - "cell_select"
707
+ - "select_all"
708
+ - "row_select"
709
+ - "column_select"
710
+ - "drag_select_cells"
711
+ - "drag_select_rows"
712
+ - "drag_select_columns"
713
+ - "shift_cell_select"
714
+ - "shift_row_select"
715
+ - "shift_column_select"
716
+ - "ctrl_cell_select"
717
+ - "ctrl_row_select"
718
+ - "ctrl_column_select"
719
+ - "deselect"
720
+ - "all_select_events", "select", "selectevents", "select_events"
721
+ - "all_modified_events", "sheetmodified", "sheet_modified" "modified_events", "modified"
722
+ - "bind_all"
723
+ - "unbind_all"
724
+ """
622
725
  # bindings is None, unbind all
623
726
  if bindings is None:
624
727
  bindings = "all"
@@ -944,6 +1047,21 @@ class Sheet(tk.Frame):
944
1047
  func: Callable,
945
1048
  add: str | None = None,
946
1049
  ) -> Sheet:
1050
+ """
1051
+ In addition to normal use, the following special tksheet bindings can be used:
1052
+ - "<<SheetModified>>"
1053
+ - "<<SheetRedrawn>>"
1054
+ - "<<SheetSelect>>"
1055
+ - "<<Copy>>"
1056
+ - "<<Cut>>"
1057
+ - "<<Paste>>"
1058
+ - "<<Delete>>"
1059
+ - "<<Undo>>"
1060
+ - "<<Redo>>"
1061
+ - "<<SelectAll>>"
1062
+
1063
+ Use `add` parameter to bind to multiple functions
1064
+ """
947
1065
  if binding == "<ButtonPress-1>":
948
1066
  self.MT.extra_b1_press_func = func
949
1067
  self.CH.extra_b1_press_func = func
@@ -2564,7 +2682,7 @@ class Sheet(tk.Frame):
2564
2682
  edit_data: bool = True,
2565
2683
  set_values: dict[tuple[int, int], object] = {},
2566
2684
  set_value: object = None,
2567
- state: str = "normal",
2685
+ state: Literal["normal", "readonly", "disabled"] = "normal",
2568
2686
  redraw: bool = True,
2569
2687
  selection_function: Callable | None = None,
2570
2688
  modified_function: Callable | None = None,
@@ -2675,7 +2793,7 @@ class Sheet(tk.Frame):
2675
2793
  *key: CreateSpanTypes,
2676
2794
  edit_data: bool = True,
2677
2795
  checked: bool | None = None,
2678
- state: str = "normal",
2796
+ state: Literal["normal", "disabled"] = "normal",
2679
2797
  redraw: bool = True,
2680
2798
  check_function: Callable | None = None,
2681
2799
  text: str = "",
@@ -5477,7 +5595,7 @@ class Sheet(tk.Frame):
5477
5595
  def selection_add(self, *items, run_binding: bool = True, redraw: bool = True) -> Sheet:
5478
5596
  to_open = []
5479
5597
  quick_displayed_check = set(self.MT.displayed_rows)
5480
- for item in unpack(items):
5598
+ for item in filter(self.RI.tree.__contains__, unpack(items)):
5481
5599
  if self.RI.tree_rns[item] not in quick_displayed_check and self.RI.tree[item].parent:
5482
5600
  to_open.extend(list(self.RI.get_iid_ancestors(item)))
5483
5601
  if to_open:
@@ -5492,7 +5610,7 @@ class Sheet(tk.Frame):
5492
5610
  self.MT.displayed_rows,
5493
5611
  self.RI.tree_rns[item],
5494
5612
  )
5495
- for item in unpack(items)
5613
+ for item in filter(self.RI.tree.__contains__, unpack(items))
5496
5614
  )
5497
5615
  ):
5498
5616
  self.MT.create_selection_box(
@@ -7058,6 +7176,10 @@ class Dropdown(Sheet):
7058
7176
  parent: tk.Misc,
7059
7177
  r: int,
7060
7178
  c: int,
7179
+ bg: str,
7180
+ fg: str,
7181
+ select_bg: str,
7182
+ select_fg: str,
7061
7183
  ops: dict,
7062
7184
  outline_color: str,
7063
7185
  width: int | None = None,
@@ -7067,6 +7189,7 @@ class Dropdown(Sheet):
7067
7189
  values: list[object] = [],
7068
7190
  close_dropdown_window: Callable | None = None,
7069
7191
  search_function: Callable = dropdown_search_function,
7192
+ modified_function: None | Callable = None,
7070
7193
  arrowkey_RIGHT: Callable | None = None,
7071
7194
  arrowkey_LEFT: Callable | None = None,
7072
7195
  align: str = "w",
@@ -7095,7 +7218,6 @@ class Dropdown(Sheet):
7095
7218
  )
7096
7219
  self.parent = parent
7097
7220
  self.close_dropdown_window = close_dropdown_window
7098
- self.search_function = search_function
7099
7221
  self.arrowkey_RIGHT = arrowkey_RIGHT
7100
7222
  self.arrowkey_LEFT = arrowkey_LEFT
7101
7223
  self.single_index = single_index
@@ -7109,12 +7231,32 @@ class Dropdown(Sheet):
7109
7231
  self.bind("<Prior>", self.arrowkey_UP)
7110
7232
  self.bind("<Next>", self.arrowkey_DOWN)
7111
7233
  self.bind("<Return>", self.b1)
7112
- self.reset(r, c, width, height, font, ops, outline_color, align, values)
7234
+ self.reset(
7235
+ r=r,
7236
+ c=c,
7237
+ bg=bg,
7238
+ fg=fg,
7239
+ select_bg=select_bg,
7240
+ select_fg=select_fg,
7241
+ width=width,
7242
+ height=height,
7243
+ font=font,
7244
+ ops=ops,
7245
+ outline_color=outline_color,
7246
+ align=align,
7247
+ values=values,
7248
+ search_function=search_function,
7249
+ modified_function=modified_function,
7250
+ )
7113
7251
 
7114
7252
  def reset(
7115
7253
  self,
7116
7254
  r: int,
7117
7255
  c: int,
7256
+ bg: str,
7257
+ fg: str,
7258
+ select_bg: str,
7259
+ select_fg: str,
7118
7260
  width: int,
7119
7261
  height: int,
7120
7262
  font: tuple[str, int, str],
@@ -7122,26 +7264,30 @@ class Dropdown(Sheet):
7122
7264
  outline_color: str,
7123
7265
  align: str,
7124
7266
  values: list[object] | None = None,
7267
+ search_function: Callable = dropdown_search_function,
7268
+ modified_function: None | Callable = None,
7125
7269
  ) -> None:
7126
7270
  self.deselect(redraw=False)
7127
7271
  self.r = r
7128
7272
  self.c = c
7129
7273
  self.row = -1
7274
+ self.search_function = search_function
7275
+ self.modified_function = modified_function
7130
7276
  self.height_and_width(height=height, width=width)
7131
7277
  self.table_align(align)
7132
7278
  self.set_options(
7133
7279
  outline_color=outline_color,
7134
- table_grid_fg=ops.popup_menu_fg,
7135
- table_selected_cells_border_fg=ops.popup_menu_fg,
7136
- table_selected_cells_bg=ops.popup_menu_highlight_bg,
7137
- table_selected_rows_border_fg=ops.popup_menu_fg,
7138
- table_selected_rows_bg=ops.popup_menu_highlight_bg,
7139
- table_selected_rows_fg=ops.popup_menu_highlight_fg,
7140
- table_selected_box_cells_fg=ops.popup_menu_highlight_bg,
7141
- table_selected_box_rows_fg=ops.popup_menu_highlight_bg,
7280
+ table_grid_fg=fg,
7281
+ table_selected_cells_border_fg=fg,
7282
+ table_selected_cells_bg=select_bg,
7283
+ table_selected_rows_border_fg=fg,
7284
+ table_selected_rows_bg=select_bg,
7285
+ table_selected_rows_fg=select_fg,
7286
+ table_selected_box_cells_fg=select_bg,
7287
+ table_selected_box_rows_fg=select_bg,
7142
7288
  font=font,
7143
- table_fg=ops.popup_menu_fg,
7144
- table_bg=ops.popup_menu_bg,
7289
+ table_fg=fg,
7290
+ table_bg=bg,
7145
7291
  **{k: ops[k] for k in scrollbar_options_keys},
7146
7292
  )
7147
7293
  self.values(values, width=width - self.yscroll.winfo_width() - 4)
@@ -7160,13 +7306,14 @@ class Dropdown(Sheet):
7160
7306
  self.see(self.row, 0, redraw=False)
7161
7307
  self.select_row(self.row)
7162
7308
 
7163
- def search_and_see(self, event: object = None) -> None:
7309
+ def search_and_see(self, event: object = None) -> str:
7164
7310
  if self.search_function is not None:
7165
7311
  rn = self.search_function(search_for=rf"{event['value']}".lower(), data=self.MT.data)
7166
- if rn is not None:
7312
+ if isinstance(rn, int):
7167
7313
  self.row = rn
7168
7314
  self.see(self.row, 0, redraw=False)
7169
7315
  self.select_row(self.row)
7316
+ return self.MT.data[rn][0]
7170
7317
 
7171
7318
  def mouse_motion(self, event: object) -> None:
7172
7319
  row = self.identify_row(event, exclude_index=True, allow_end=False)