tksheet 7.2.12__tar.gz → 7.2.14__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.12/tksheet.egg-info → tksheet-7.2.14}/PKG-INFO +4 -4
  2. {tksheet-7.2.12 → tksheet-7.2.14}/README.md +3 -3
  3. {tksheet-7.2.12 → tksheet-7.2.14}/pyproject.toml +1 -1
  4. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/__init__.py +2 -1
  5. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/column_headers.py +1 -3
  6. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/functions.py +62 -1
  7. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/main_table.py +51 -61
  8. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/row_index.py +45 -36
  9. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/sheet.py +30 -14
  10. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/sheet_options.py +4 -0
  11. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/text_editor.py +1 -1
  12. {tksheet-7.2.12 → tksheet-7.2.14/tksheet.egg-info}/PKG-INFO +4 -4
  13. {tksheet-7.2.12 → tksheet-7.2.14}/LICENSE.txt +0 -0
  14. {tksheet-7.2.12 → tksheet-7.2.14}/setup.cfg +0 -0
  15. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/colors.py +0 -0
  16. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/formatters.py +0 -0
  17. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/other_classes.py +0 -0
  18. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/themes.py +0 -0
  19. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/top_left_rectangle.py +0 -0
  20. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/types.py +0 -0
  21. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet/vars.py +0 -0
  22. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet.egg-info/SOURCES.txt +0 -0
  23. {tksheet-7.2.12 → tksheet-7.2.14}/tksheet.egg-info/dependency_links.txt +0 -0
  24. {tksheet-7.2.12 → tksheet-7.2.14}/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.12
3
+ Version: 7.2.14
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
@@ -103,10 +103,10 @@ sheet.insert_columns(columns=2, idx=4, undo=True)
103
103
  sheet.delete_columns(columns=[0, 3], undo=True)
104
104
  ```
105
105
 
106
- ### **light green theme**
106
+ ### **light blue theme**
107
107
 
108
- ![tksheet light green theme](https://github.com/ragardner/tksheet/assets/26602401/790ee9bd-b4de-48df-8c44-33f303061d84)
108
+ ![tksheet light blue theme](https://github.com/user-attachments/assets/f40317d7-8b7f-43c5-9217-a77168b068ed)
109
109
 
110
110
  ### **dark theme**
111
111
 
112
- ![tksheet dark theme](https://github.com/ragardner/tksheet/assets/26602401/fc8a0407-1486-46cf-b852-9bcff23160e5)
112
+ ![tksheet dark theme](https://github.com/user-attachments/assets/288453d6-5ac1-4d45-827f-45b24a3d05ed)
@@ -61,10 +61,10 @@ sheet.insert_columns(columns=2, idx=4, undo=True)
61
61
  sheet.delete_columns(columns=[0, 3], undo=True)
62
62
  ```
63
63
 
64
- ### **light green theme**
64
+ ### **light blue theme**
65
65
 
66
- ![tksheet light green theme](https://github.com/ragardner/tksheet/assets/26602401/790ee9bd-b4de-48df-8c44-33f303061d84)
66
+ ![tksheet light blue theme](https://github.com/user-attachments/assets/f40317d7-8b7f-43c5-9217-a77168b068ed)
67
67
 
68
68
  ### **dark theme**
69
69
 
70
- ![tksheet dark theme](https://github.com/ragardner/tksheet/assets/26602401/fc8a0407-1486-46cf-b852-9bcff23160e5)
70
+ ![tksheet dark theme](https://github.com/user-attachments/assets/288453d6-5ac1-4d45-827f-45b24a3d05ed)
@@ -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.12"
9
+ version = "7.2.14"
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.12"
7
+ __version__ = "7.2.14"
8
8
 
9
9
  from .colors import (
10
10
  color_map,
@@ -37,6 +37,7 @@ from .functions import (
37
37
  alpha2num,
38
38
  consecutive_chunks,
39
39
  consecutive_ranges,
40
+ convert_align,
40
41
  data_to_displayed_idxs,
41
42
  displayed_to_data_idxs,
42
43
  dropdown_search_function,
@@ -128,7 +128,6 @@ class ColumnHeaders(tk.Canvas):
128
128
  self.hidd_checkbox = {}
129
129
  self.hidd_boxes = set()
130
130
 
131
- self.default_header = kwargs["default_header"].lower()
132
131
  self.align = kwargs["header_align"]
133
132
  self.basic_bindings()
134
133
 
@@ -1438,7 +1437,6 @@ class ColumnHeaders(tk.Canvas):
1438
1437
  x_stop,
1439
1438
  self.current_height,
1440
1439
  )
1441
- draw_x = self.MT.col_positions[grid_start_col]
1442
1440
  yend = self.current_height - 5
1443
1441
  if (self.PAR.ops.show_vertical_grid or self.width_resizing_enabled) and col_pos_exists:
1444
1442
  points = [
@@ -2270,7 +2268,7 @@ class ColumnHeaders(tk.Canvas):
2270
2268
  except Exception:
2271
2269
  value = ""
2272
2270
  if not value and self.PAR.ops.show_default_header_for_empty:
2273
- value = get_n2a(datacn, self.default_header)
2271
+ value = get_n2a(datacn, self.PAR.ops.default_header)
2274
2272
  return value
2275
2273
 
2276
2274
  def get_value_for_empty_cell(self, datacn: int, c_ops: bool = True) -> object:
@@ -37,8 +37,17 @@ unpickle_obj = pickle.loads
37
37
 
38
38
 
39
39
  def get_csv_str_dialect(s: str, delimiters: str) -> csv.Dialect:
40
+ if len(s) > 6000:
41
+ try:
42
+ _upto = next(
43
+ match.start() + 1 for i, match in enumerate(re.finditer("\n", s), 1) if i == 300 or match.start() > 6000
44
+ )
45
+ except Exception:
46
+ _upto = len(s)
47
+ else:
48
+ _upto = len(s)
40
49
  try:
41
- return csv.Sniffer().sniff(s[:5000] if len(s) > 5000 else s, delimiters=delimiters)
50
+ return csv.Sniffer().sniff(s[:_upto] if len(s) > 6000 else s, delimiters=delimiters)
42
51
  except Exception:
43
52
  return csv.excel_tab
44
53
 
@@ -430,6 +439,58 @@ def is_contiguous(iterable: Iterator[int]) -> bool:
430
439
  return all(i == (prev := prev + 1) for i in itr)
431
440
 
432
441
 
442
+ def down_cell_within_box(
443
+ r: int,
444
+ c: int,
445
+ r1: int,
446
+ c1: int,
447
+ r2: int,
448
+ c2: int,
449
+ numrows: int,
450
+ numcols: int,
451
+ ) -> tuple[int, int]:
452
+ moved = False
453
+ new_r = r
454
+ new_c = c
455
+ if r + 1 == r2:
456
+ new_r = r1
457
+ elif numrows > 1:
458
+ new_r = r + 1
459
+ moved = True
460
+ if not moved:
461
+ if c + 1 == c2:
462
+ new_c = c1
463
+ elif numcols > 1:
464
+ new_c = c + 1
465
+ return new_r, new_c
466
+
467
+
468
+ def cell_right_within_box(
469
+ r: int,
470
+ c: int,
471
+ r1: int,
472
+ c1: int,
473
+ r2: int,
474
+ c2: int,
475
+ numrows: int,
476
+ numcols: int,
477
+ ) -> tuple[int, int]:
478
+ moved = False
479
+ new_r = r
480
+ new_c = c
481
+ if c + 1 == c2:
482
+ new_c = c1
483
+ elif numcols > 1:
484
+ new_c = c + 1
485
+ moved = True
486
+ if not moved:
487
+ if r + 1 == r2:
488
+ new_r = r1
489
+ elif numrows > 1:
490
+ new_r = r + 1
491
+ return new_r, new_c
492
+
493
+
433
494
  def get_last(
434
495
  it: Iterator,
435
496
  ) -> object:
@@ -54,6 +54,7 @@ from .functions import (
54
54
  decompress_load,
55
55
  diff_gen,
56
56
  diff_list,
57
+ down_cell_within_box,
57
58
  event_dict,
58
59
  gen_formatted,
59
60
  get_data_from_clipboard,
@@ -72,6 +73,7 @@ from .functions import (
72
73
  new_tk_event,
73
74
  pickle_obj,
74
75
  pickled_event_dict,
76
+ cell_right_within_box,
75
77
  rounded_box_coords,
76
78
  span_idxs_post_move,
77
79
  try_binding,
@@ -6345,7 +6347,7 @@ class MainTable(tk.Canvas):
6345
6347
  for r in range(box.coords.from_r, box.coords.upto_r)
6346
6348
  }
6347
6349
  if get_cells_as_rows:
6348
- return s | set(tup[0] for tup in self.get_selected_cells())
6350
+ return s | set(map(itemgetter(0), self.gen_selected_cells()))
6349
6351
  return s
6350
6352
 
6351
6353
  def get_selected_cols(
@@ -6369,7 +6371,7 @@ class MainTable(tk.Canvas):
6369
6371
  for c in range(box.coords.from_c, box.coords.upto_c)
6370
6372
  }
6371
6373
  if get_cells_as_cols:
6372
- return s | set(tup[1] for tup in self.get_selected_cells())
6374
+ return s | set(map(itemgetter(1), self.gen_selected_cells()))
6373
6375
  return s
6374
6376
 
6375
6377
  def get_selected_cells(
@@ -6782,63 +6784,63 @@ class MainTable(tk.Canvas):
6782
6784
  numrows = r2 - r1
6783
6785
  if numcols == 1 and numrows == 1:
6784
6786
  if event.keysym == "Return":
6785
- self.select_cell(r + 1 if r < len(self.row_positions) - 2 else r, c)
6786
- self.see(
6787
- r + 1 if r < len(self.row_positions) - 2 else r,
6788
- c,
6789
- keep_xscroll=True,
6790
- bottom_right_corner=True,
6791
- check_cell_visibility=True,
6792
- )
6787
+ if self.PAR.ops.edit_cell_return == "right":
6788
+ self.select_right(r, c)
6789
+ if self.PAR.ops.edit_cell_return == "down":
6790
+ self.select_down(r, c)
6791
+ elif event.keysym == "Tab":
6792
+ if self.PAR.ops.edit_cell_tab == "right":
6793
+ self.select_right(r, c)
6794
+ if self.PAR.ops.edit_cell_tab == "down":
6795
+ self.select_down(r, c)
6796
+ else:
6797
+ if event.keysym == "Return":
6798
+ if self.PAR.ops.edit_cell_return == "right":
6799
+ new_r, new_c = cell_right_within_box(r, c, r1, c1, r2, c2, numrows, numcols)
6800
+ elif self.PAR.ops.edit_cell_return == "down":
6801
+ new_r, new_c = down_cell_within_box(r, c, r1, c1, r2, c2, numrows, numcols)
6802
+ else:
6803
+ new_r, new_c = None, None
6793
6804
  elif event.keysym == "Tab":
6794
- self.select_cell(r, c + 1 if c < len(self.col_positions) - 2 else c)
6805
+ if self.PAR.ops.edit_cell_tab == "right":
6806
+ new_r, new_c = cell_right_within_box(r, c, r1, c1, r2, c2, numrows, numcols)
6807
+ elif self.PAR.ops.edit_cell_tab == "down":
6808
+ new_r, new_c = down_cell_within_box(r, c, r1, c1, r2, c2, numrows, numcols)
6809
+ else:
6810
+ new_r, new_c = None, None
6811
+ if isinstance(new_r, int):
6812
+ self.set_currently_selected(new_r, new_c, item=self.selected.fill_iid)
6795
6813
  self.see(
6796
- r,
6797
- c + 1 if c < len(self.col_positions) - 2 else c,
6798
- keep_xscroll=True,
6814
+ new_r,
6815
+ new_c,
6816
+ keep_xscroll=False,
6799
6817
  bottom_right_corner=True,
6800
6818
  check_cell_visibility=True,
6801
6819
  )
6802
- else:
6803
- moved = False
6804
- new_r = r
6805
- new_c = c
6806
- if event.keysym == "Return":
6807
- if r + 1 == r2:
6808
- new_r = r1
6809
- elif numrows > 1:
6810
- new_r = r + 1
6811
- moved = True
6812
- if not moved:
6813
- if c + 1 == c2:
6814
- new_c = c1
6815
- elif numcols > 1:
6816
- new_c = c + 1
6817
- elif event.keysym == "Tab":
6818
- if c + 1 == c2:
6819
- new_c = c1
6820
- elif numcols > 1:
6821
- new_c = c + 1
6822
- moved = True
6823
- if not moved:
6824
- if r + 1 == r2:
6825
- new_r = r1
6826
- elif numrows > 1:
6827
- new_r = r + 1
6828
- self.set_currently_selected(new_r, new_c, item=self.selected.fill_iid)
6829
- self.see(
6830
- new_r,
6831
- new_c,
6832
- keep_xscroll=False,
6833
- bottom_right_corner=True,
6834
- check_cell_visibility=True,
6835
- )
6836
6820
  self.recreate_all_selection_boxes()
6837
6821
  self.hide_text_editor_and_dropdown()
6838
6822
  if event.keysym != "FocusOut":
6839
6823
  self.focus_set()
6840
6824
  return "break"
6841
6825
 
6826
+ def select_right(self, r: int, c: int) -> None:
6827
+ self.select_cell(r, c + 1 if c < len(self.col_positions) - 2 else c)
6828
+ self.see(
6829
+ r,
6830
+ c + 1 if c < len(self.col_positions) - 2 else c,
6831
+ bottom_right_corner=True,
6832
+ check_cell_visibility=True,
6833
+ )
6834
+
6835
+ def select_down(self, r: int, c: int) -> None:
6836
+ self.select_cell(r + 1 if r < len(self.row_positions) - 2 else r, c)
6837
+ self.see(
6838
+ r + 1 if r < len(self.row_positions) - 2 else r,
6839
+ c,
6840
+ bottom_right_corner=True,
6841
+ check_cell_visibility=True,
6842
+ )
6843
+
6842
6844
  def tab_key(self, event: object = None) -> str:
6843
6845
  if not self.selected:
6844
6846
  return
@@ -6851,19 +6853,7 @@ class MainTable(tk.Canvas):
6851
6853
  new_c = c + 1 if c < len(self.col_positions) - 2 else c
6852
6854
  self.select_cell(new_r, new_c)
6853
6855
  else:
6854
- moved = False
6855
- new_r = r
6856
- new_c = c
6857
- if c + 1 == c2:
6858
- new_c = c1
6859
- elif numcols > 1:
6860
- new_c = c + 1
6861
- moved = True
6862
- if not moved:
6863
- if r + 1 == r2:
6864
- new_r = r1
6865
- elif numrows > 1:
6866
- new_r = r + 1
6856
+ new_r, new_c = cell_right_within_box(r, c, r1, c1, r2, c2, numrows, numcols)
6867
6857
  self.set_currently_selected(new_r, new_c, item=self.selected.fill_iid)
6868
6858
  self.see(
6869
6859
  new_r,
@@ -140,7 +140,6 @@ class RowIndex(tk.Canvas):
140
140
  self.hidd_boxes = set()
141
141
 
142
142
  self.align = kwargs["row_index_align"]
143
- self.default_index = kwargs["default_row_index"].lower()
144
143
 
145
144
  self.tree_reset()
146
145
  self.basic_bindings()
@@ -1200,11 +1199,11 @@ class RowIndex(tk.Canvas):
1200
1199
 
1201
1200
  def auto_set_index_width(self, end_row: int, only_rows: list) -> bool:
1202
1201
  if not isinstance(self.MT._row_index, int) and not self.MT._row_index:
1203
- if self.default_index == "letters":
1202
+ if self.PAR.ops.default_row_index == "letters":
1204
1203
  new_w = self.MT.get_txt_w(f"{num2alpha(end_row)}") + 20
1205
- elif self.default_index == "numbers":
1204
+ elif self.PAR.ops.default_row_index == "numbers":
1206
1205
  new_w = self.MT.get_txt_w(f"{end_row}") + 20
1207
- elif self.default_index == "both":
1206
+ elif self.PAR.ops.default_row_index == "both":
1208
1207
  new_w = self.MT.get_txt_w(f"{end_row + 1} {num2alpha(end_row)}") + 20
1209
1208
  elif self.PAR.ops.auto_resize_row_index is True:
1210
1209
  new_w = self.get_index_text_width(only_rows=only_rows)
@@ -1336,33 +1335,44 @@ class RowIndex(tk.Canvas):
1336
1335
  fill: str,
1337
1336
  tag: str | tuple[str],
1338
1337
  indent: float,
1338
+ has_children: bool = False,
1339
1339
  open_: bool = False,
1340
1340
  ) -> None:
1341
1341
  mod = (self.MT.index_txt_height - 1) if self.MT.index_txt_height % 2 else self.MT.index_txt_height
1342
1342
  small_mod = int(mod / 5)
1343
1343
  mid_y = floor(self.MT.min_row_height / 2)
1344
- # up arrow
1345
- if open_:
1346
- points = (
1347
- # the left hand downward point
1348
- x1 + 5 + indent,
1349
- y1 + mid_y + small_mod,
1350
- # the middle upward point
1351
- x1 + 5 + indent + small_mod + small_mod,
1352
- y1 + mid_y - small_mod,
1353
- # the right hand downward point
1354
- x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
1355
- y1 + mid_y + small_mod,
1356
- )
1357
- # right pointing arrow
1344
+ if has_children:
1345
+ # up arrow
1346
+ if open_:
1347
+ points = (
1348
+ # the left hand downward point
1349
+ x1 + 5 + indent,
1350
+ y1 + mid_y + small_mod,
1351
+ # the middle upward point
1352
+ x1 + 5 + indent + small_mod + small_mod,
1353
+ y1 + mid_y - small_mod,
1354
+ # the right hand downward point
1355
+ x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
1356
+ y1 + mid_y + small_mod,
1357
+ )
1358
+ # right pointing arrow
1359
+ else:
1360
+ points = (
1361
+ # the upper point
1362
+ x1 + 5 + indent + small_mod + small_mod,
1363
+ y1 + mid_y - small_mod - small_mod,
1364
+ # the middle point
1365
+ x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
1366
+ y1 + mid_y,
1367
+ # the bottom point
1368
+ x1 + 5 + indent + small_mod + small_mod,
1369
+ y1 + mid_y + small_mod + small_mod,
1370
+ )
1358
1371
  else:
1359
1372
  points = (
1360
1373
  # the upper point
1361
1374
  x1 + 5 + indent + small_mod + small_mod,
1362
1375
  y1 + mid_y - small_mod - small_mod,
1363
- # the middle point
1364
- x1 + 5 + indent + small_mod + small_mod + small_mod + small_mod,
1365
- y1 + mid_y,
1366
1376
  # the bottom point
1367
1377
  x1 + 5 + indent + small_mod + small_mod,
1368
1378
  y1 + mid_y + small_mod + small_mod,
@@ -1371,14 +1381,14 @@ class RowIndex(tk.Canvas):
1371
1381
  t, sh = self.hidd_tree_arrow.popitem()
1372
1382
  self.coords(t, points)
1373
1383
  if sh:
1374
- self.itemconfig(t, fill=fill)
1384
+ self.itemconfig(t, fill=fill if has_children else self.PAR.ops.index_grid_fg)
1375
1385
  else:
1376
- self.itemconfig(t, fill=fill, tag=tag, state="normal")
1386
+ self.itemconfig(t, fill=fill if has_children else self.PAR.ops.index_grid_fg, tag=tag, state="normal")
1377
1387
  self.lift(t)
1378
1388
  else:
1379
1389
  t = self.create_line(
1380
1390
  points,
1381
- fill=fill,
1391
+ fill=fill if has_children else self.PAR.ops.index_grid_fg,
1382
1392
  tag=tag,
1383
1393
  width=2,
1384
1394
  capstyle=tk.ROUND,
@@ -1525,7 +1535,6 @@ class RowIndex(tk.Canvas):
1525
1535
  self.hidd_tree_arrow.update(self.disp_tree_arrow)
1526
1536
  self.disp_tree_arrow = {}
1527
1537
  self.visible_row_dividers = {}
1528
- draw_y = self.MT.row_positions[grid_start_row]
1529
1538
  xend = self.current_width - 6
1530
1539
  self.row_width_resize_bbox = (
1531
1540
  self.current_width - 2,
@@ -1689,16 +1698,16 @@ class RowIndex(tk.Canvas):
1689
1698
  draw_x += self.MT.index_txt_height + 3
1690
1699
  indent = self.get_treeview_indent(iid)
1691
1700
  draw_x += indent + 5
1692
- if self.tree[iid].children:
1693
- self.redraw_tree_arrow(
1694
- 2,
1695
- rtopgridln,
1696
- r=r,
1697
- fill=tree_arrow_fg,
1698
- tag="ta",
1699
- indent=indent,
1700
- open_=self.MT._row_index[datarn].iid in self.tree_open_ids,
1701
- )
1701
+ self.redraw_tree_arrow(
1702
+ 2,
1703
+ rtopgridln,
1704
+ r=r,
1705
+ fill=tree_arrow_fg,
1706
+ tag="ta",
1707
+ indent=indent,
1708
+ has_children=bool(self.tree[iid].children),
1709
+ open_=self.MT._row_index[datarn].iid in self.tree_open_ids,
1710
+ )
1702
1711
  lns = self.get_valid_cell_data_as_str(datarn, fix=False)
1703
1712
  if not lns:
1704
1713
  continue
@@ -2388,7 +2397,7 @@ class RowIndex(tk.Canvas):
2388
2397
  except Exception:
2389
2398
  value = ""
2390
2399
  if not value and self.PAR.ops.show_default_index_for_empty:
2391
- value = get_n2a(datarn, self.default_index)
2400
+ value = get_n2a(datarn, self.PAR.ops.default_row_index)
2392
2401
  return value
2393
2402
 
2394
2403
  def get_value_for_empty_cell(self, datarn: int, r_ops: bool = True) -> object:
@@ -188,6 +188,8 @@ class Sheet(tk.Frame):
188
188
  show_horizontal_grid: bool = True,
189
189
  display_selected_fg_over_highlights: bool = False,
190
190
  show_selected_cells_border: bool = True,
191
+ edit_cell_tab: Literal["right", "down", ""] = "right",
192
+ edit_cell_return: Literal["right", "down", ""] = "down",
191
193
  treeview: bool = False,
192
194
  treeview_indent: str | int = "6",
193
195
  rounded_boxes: bool = True,
@@ -339,11 +341,9 @@ class Sheet(tk.Frame):
339
341
  row_index_align=(
340
342
  convert_align(row_index_align) if row_index_align is not None else convert_align(index_align)
341
343
  ),
342
- default_row_index=default_row_index,
343
344
  )
344
345
  self.CH = ColumnHeaders(
345
346
  parent=self,
346
- default_header=default_header,
347
347
  header_align=convert_align(header_align),
348
348
  )
349
349
  self.MT = MainTable(
@@ -1502,6 +1502,8 @@ class Sheet(tk.Frame):
1502
1502
  if displayed_rows:
1503
1503
  self.MT.displayed_rows = []
1504
1504
  self.MT.all_rows_displayed = True
1505
+ if selections:
1506
+ self.MT.deselect(redraw=False)
1505
1507
  if row_heights:
1506
1508
  self.MT.saved_row_heights = {}
1507
1509
  self.MT.set_row_positions([])
@@ -1514,8 +1516,6 @@ class Sheet(tk.Frame):
1514
1516
  self.MT.reset_tags()
1515
1517
  if undo_stack:
1516
1518
  self.reset_undos()
1517
- if selections:
1518
- self.MT.deselect(redraw=False)
1519
1519
  if sheet_options:
1520
1520
  self.ops = new_sheet_options()
1521
1521
  self.change_theme(redraw=False)
@@ -2924,7 +2924,7 @@ class Sheet(tk.Frame):
2924
2924
 
2925
2925
  def table_align(
2926
2926
  self,
2927
- align: str = None,
2927
+ align: str | None = None,
2928
2928
  redraw: bool = True,
2929
2929
  ) -> str | Sheet:
2930
2930
  if align is None:
@@ -2937,7 +2937,7 @@ class Sheet(tk.Frame):
2937
2937
 
2938
2938
  def header_align(
2939
2939
  self,
2940
- align: str = None,
2940
+ align: str | None = None,
2941
2941
  redraw: bool = True,
2942
2942
  ) -> str | Sheet:
2943
2943
  if align is None:
@@ -2950,7 +2950,7 @@ class Sheet(tk.Frame):
2950
2950
 
2951
2951
  def row_index_align(
2952
2952
  self,
2953
- align: str = None,
2953
+ align: str | None = None,
2954
2954
  redraw: bool = True,
2955
2955
  ) -> str | Sheet:
2956
2956
  if align is None:
@@ -3461,6 +3461,17 @@ class Sheet(tk.Frame):
3461
3461
  return self.MT.row_positions
3462
3462
  return self.MT.get_row_heights()
3463
3463
 
3464
+ def get_safe_row_heights(self) -> list[int]:
3465
+ default_h = self.MT.get_default_row_height()
3466
+ return [0 if e == default_h else e for e in self.MT.gen_row_heights()]
3467
+
3468
+ def set_safe_row_heights(self, heights: list[int]) -> Sheet:
3469
+ default_h = self.MT.get_default_row_height()
3470
+ self.MT.row_positions = list(
3471
+ accumulate(chain([0], (self.valid_row_height(e) if e else default_h for e in heights)))
3472
+ )
3473
+ return self
3474
+
3464
3475
  def get_row_text_height(
3465
3476
  self,
3466
3477
  row: int,
@@ -3823,8 +3834,14 @@ class Sheet(tk.Frame):
3823
3834
  return c if self.MT.all_columns_displayed else self.MT.displayed_columns[c]
3824
3835
 
3825
3836
  data_c = displayed_column_to_data
3837
+ datacn = displayed_column_to_data
3826
3838
  dcol = displayed_column_to_data
3827
3839
 
3840
+ def data_column_to_displayed(self, c: int) -> int:
3841
+ return self.MT.dispcn(c)
3842
+
3843
+ dispcn = data_column_to_displayed
3844
+
3828
3845
  def display_columns(
3829
3846
  self,
3830
3847
  columns: None | Literal["all"] | Iterator[int] = None,
@@ -3951,8 +3968,14 @@ class Sheet(tk.Frame):
3951
3968
  return r if self.MT.all_rows_displayed else self.MT.displayed_rows[r]
3952
3969
 
3953
3970
  data_r = displayed_row_to_data
3971
+ datarn = displayed_row_to_data
3954
3972
  drow = displayed_row_to_data
3955
3973
 
3974
+ def data_row_to_displayed(self, r: int) -> int:
3975
+ return self.MT.disprn(r)
3976
+
3977
+ disprn = data_row_to_displayed
3978
+
3956
3979
  def display_rows(
3957
3980
  self,
3958
3981
  rows: None | Literal["all"] | Iterator[int] = None,
@@ -4297,10 +4320,6 @@ class Sheet(tk.Frame):
4297
4320
  )
4298
4321
  if "default_row_height" in kwargs:
4299
4322
  self.default_row_height(kwargs["default_row_height"])
4300
- if "default_header" in kwargs:
4301
- self.CH.default_header = kwargs["default_header"].lower()
4302
- if "default_row_index" in kwargs:
4303
- self.RI.default_index = kwargs["default_row_index"].lower()
4304
4323
  if "max_column_width" in kwargs:
4305
4324
  self.MT.max_column_width = float(kwargs["max_column_width"])
4306
4325
  if "max_row_height" in kwargs:
@@ -6675,9 +6694,6 @@ class Sheet(tk.Frame):
6675
6694
  if self.RI.get_cell_kwargs(r, key="dropdown"):
6676
6695
  return self.MT._row_index[r]
6677
6696
 
6678
- def delete_all_formatting(self, clear_values: bool = False) -> None:
6679
- self.MT.delete_all_formatting(clear_values=clear_values)
6680
-
6681
6697
  def format_cell(
6682
6698
  self,
6683
6699
  r: int | Literal["all"],
@@ -217,6 +217,8 @@ def new_sheet_options() -> DotDict:
217
217
  "default_row_height": "1",
218
218
  "default_column_width": 120,
219
219
  "default_row_index_width": 70,
220
+ "default_row_index": "numbers",
221
+ "default_header": "letters",
220
222
  "page_up_down_select_row": True,
221
223
  "paste_can_expand_x": False,
222
224
  "paste_can_expand_y": False,
@@ -237,6 +239,8 @@ def new_sheet_options() -> DotDict:
237
239
  "show_horizontal_grid": True,
238
240
  "display_selected_fg_over_highlights": False,
239
241
  "show_selected_cells_border": True,
242
+ "edit_cell_tab": "right",
243
+ "edit_cell_return": "down",
240
244
  "treeview": False,
241
245
  "treeview_indent": "6",
242
246
  "rounded_boxes": True,
@@ -63,7 +63,7 @@ class TextEditorTkText(tk.Text):
63
63
  state=state,
64
64
  )
65
65
  self.align = align
66
- self.rc_popup_menu.delete(0, None)
66
+ self.rc_popup_menu.delete(0, "end")
67
67
  self.rc_popup_menu.add_command(
68
68
  label=sheet_ops.select_all_label,
69
69
  accelerator=sheet_ops.select_all_accelerator,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tksheet
3
- Version: 7.2.12
3
+ Version: 7.2.14
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
@@ -103,10 +103,10 @@ sheet.insert_columns(columns=2, idx=4, undo=True)
103
103
  sheet.delete_columns(columns=[0, 3], undo=True)
104
104
  ```
105
105
 
106
- ### **light green theme**
106
+ ### **light blue theme**
107
107
 
108
- ![tksheet light green theme](https://github.com/ragardner/tksheet/assets/26602401/790ee9bd-b4de-48df-8c44-33f303061d84)
108
+ ![tksheet light blue theme](https://github.com/user-attachments/assets/f40317d7-8b7f-43c5-9217-a77168b068ed)
109
109
 
110
110
  ### **dark theme**
111
111
 
112
- ![tksheet dark theme](https://github.com/ragardner/tksheet/assets/26602401/fc8a0407-1486-46cf-b852-9bcff23160e5)
112
+ ![tksheet dark theme](https://github.com/user-attachments/assets/288453d6-5ac1-4d45-827f-45b24a3d05ed)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes