tksheet 7.4.2__py3-none-any.whl → 7.4.4__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/main_table.py CHANGED
@@ -50,7 +50,6 @@ from .functions import (
50
50
  consecutive_ranges,
51
51
  data_to_displayed_idxs,
52
52
  diff_gen,
53
- diff_list,
54
53
  down_cell_within_box,
55
54
  event_dict,
56
55
  event_has_char_key,
@@ -72,6 +71,7 @@ from .functions import (
72
71
  mod_span,
73
72
  mod_span_widget,
74
73
  move_elements_by_mapping,
74
+ move_elements_by_mapping_gen,
75
75
  new_tk_event,
76
76
  next_cell,
77
77
  push_n,
@@ -932,19 +932,21 @@ class MainTable(tk.Canvas):
932
932
  def sort_boxes(
933
933
  self,
934
934
  event: tk.Event | None = None,
935
- boxes: AnyIter[int, int, int, int] | None = None,
935
+ boxes: dict[tuple[int, int, int, int], Literal["cells", "rows", "columns"]] | None = None,
936
936
  reverse: bool = False,
937
937
  row_wise: bool = False,
938
938
  validation: bool = True,
939
939
  key: Callable | None = None,
940
940
  undo: bool = True,
941
941
  ) -> EventDataDict:
942
- if boxes is None:
942
+ if not boxes:
943
943
  boxes = self.get_boxes()
944
944
  if not boxes:
945
- boxes = [(0, 0, len(self.row_positions) - 1, len(self.col_positions) - 1)]
945
+ boxes = {Box_nt(0, 0, len(self.row_positions) - 1, len(self.col_positions) - 1): "cells"}
946
946
  event_data = self.new_event_dict("edit_table", boxes=boxes)
947
947
  try_binding(self.extra_begin_sort_cells_func, event_data)
948
+ if key is None:
949
+ key = self.PAR.ops.sort_key
948
950
  for r1, c1, r2, c2 in boxes:
949
951
  data = sort_selection(
950
952
  [[self.get_cell_data(self.datarn(r), self.datacn(c)) for c in range(c1, c2)] for r in range(r1, r2)],
@@ -1287,26 +1289,36 @@ class MainTable(tk.Canvas):
1287
1289
  data_indexes: bool = False,
1288
1290
  ) -> tuple[dict[int, int], dict[int, int], int, dict[int, int]]:
1289
1291
  if not data_indexes or self.all_columns_displayed:
1290
- disp_new_idxs = get_new_indexes(move_to=move_to, to_move=to_move)
1292
+ disp_new_idxs = get_new_indexes(
1293
+ move_to=move_to,
1294
+ to_move=to_move,
1295
+ )
1296
+ data_new_idxs = dict(disp_new_idxs)
1291
1297
  else:
1292
1298
  disp_new_idxs = {}
1299
+ data_new_idxs = get_new_indexes(
1300
+ move_to=move_to,
1301
+ to_move=to_move,
1302
+ )
1293
1303
  # at_least_cols should not be len in this case as move_to can be len
1294
1304
  fix_len = (move_to - 1) if move_to else move_to
1295
1305
  if not self.all_columns_displayed and not data_indexes:
1296
1306
  fix_len = self.datacn(fix_len)
1297
1307
  totalcols = self.equalize_data_row_lengths(at_least_cols=fix_len)
1298
- data_new_idxs = get_new_indexes(move_to=move_to, to_move=to_move)
1299
1308
  if not self.all_columns_displayed and not data_indexes:
1300
- data_new_idxs = dict(
1301
- zip(
1302
- move_elements_by_mapping(
1309
+ keep = set(map(self.datacn, to_move))
1310
+ data_new_idxs = {
1311
+ k: v
1312
+ for k, v in zip(
1313
+ move_elements_by_mapping_gen(
1303
1314
  self.displayed_columns,
1304
1315
  data_new_idxs,
1305
1316
  dict(zip(data_new_idxs.values(), data_new_idxs)),
1306
1317
  ),
1307
1318
  self.displayed_columns,
1308
- ),
1309
- )
1319
+ )
1320
+ if k in keep
1321
+ }
1310
1322
  return data_new_idxs, dict(zip(data_new_idxs.values(), data_new_idxs)), totalcols, disp_new_idxs
1311
1323
 
1312
1324
  def move_columns_adjust_options_dict(
@@ -1338,7 +1350,7 @@ class MainTable(tk.Canvas):
1338
1350
 
1339
1351
  if move_widths and disp_new_idxs:
1340
1352
  self.set_col_positions(
1341
- itr=move_elements_by_mapping(
1353
+ itr=move_elements_by_mapping_gen(
1342
1354
  self.get_column_widths(),
1343
1355
  disp_new_idxs,
1344
1356
  dict(
@@ -1537,7 +1549,7 @@ class MainTable(tk.Canvas):
1537
1549
  data_new_idxs = {
1538
1550
  k: v
1539
1551
  for k, v in zip(
1540
- move_elements_by_mapping(
1552
+ move_elements_by_mapping_gen(
1541
1553
  self.displayed_rows,
1542
1554
  data_new_idxs,
1543
1555
  dict(zip(data_new_idxs.values(), data_new_idxs)),
@@ -1732,7 +1744,7 @@ class MainTable(tk.Canvas):
1732
1744
 
1733
1745
  if move_heights and disp_new_idxs:
1734
1746
  self.set_row_positions(
1735
- itr=move_elements_by_mapping(
1747
+ itr=move_elements_by_mapping_gen(
1736
1748
  self.get_row_heights(),
1737
1749
  disp_new_idxs,
1738
1750
  dict(
@@ -1788,7 +1800,7 @@ class MainTable(tk.Canvas):
1788
1800
  old_idxs = dict(zip(new_idxs.values(), new_idxs))
1789
1801
  return dict(
1790
1802
  zip(
1791
- move_elements_by_mapping(tuple(range(max_idx + 1)), new_idxs, old_idxs),
1803
+ move_elements_by_mapping_gen(tuple(range(max_idx + 1)), new_idxs, old_idxs),
1792
1804
  range(max_idx + 1),
1793
1805
  )
1794
1806
  )
@@ -1973,7 +1985,7 @@ class MainTable(tk.Canvas):
1973
1985
  event_data = self.delete_rows_displayed(
1974
1986
  rows=tuple(reversed(modification["added"]["rows"]["row_heights"])),
1975
1987
  event_data=event_data,
1976
- restored_state=True,
1988
+ from_undo=True,
1977
1989
  )
1978
1990
 
1979
1991
  if modification["added"]["columns"]:
@@ -1985,7 +1997,7 @@ class MainTable(tk.Canvas):
1985
1997
  event_data = self.delete_columns_displayed(
1986
1998
  cols=tuple(reversed(modification["added"]["columns"]["column_widths"])),
1987
1999
  event_data=event_data,
1988
- restored_state=True,
2000
+ from_undo=True,
1989
2001
  )
1990
2002
 
1991
2003
  if modification["deleted"]["rows"] or modification["deleted"]["row_heights"]:
@@ -1998,7 +2010,7 @@ class MainTable(tk.Canvas):
1998
2010
  create_ops=False,
1999
2011
  create_selections=False,
2000
2012
  add_col_positions=False,
2001
- restored_state=True,
2013
+ from_undo=True,
2002
2014
  )
2003
2015
 
2004
2016
  if modification["deleted"]["columns"] or modification["deleted"]["column_widths"]:
@@ -2010,7 +2022,7 @@ class MainTable(tk.Canvas):
2010
2022
  create_ops=False,
2011
2023
  create_selections=False,
2012
2024
  add_row_positions=False,
2013
- restored_state=True,
2025
+ from_undo=True,
2014
2026
  )
2015
2027
 
2016
2028
  if modification["eventname"].startswith(("edit", "move")):
@@ -4489,10 +4501,10 @@ class MainTable(tk.Canvas):
4489
4501
  self.set_row_positions(itr=(h for i, h in enumerate(self.gen_row_heights()) if i not in idxs))
4490
4502
 
4491
4503
  def get_column_widths(self) -> list[int]:
4492
- return diff_list(self.col_positions)
4504
+ return list(diff_gen(self.col_positions))
4493
4505
 
4494
4506
  def get_row_heights(self) -> list[int]:
4495
- return diff_list(self.row_positions)
4507
+ return list(diff_gen(self.row_positions))
4496
4508
 
4497
4509
  def gen_column_widths(self) -> Generator[int]:
4498
4510
  return diff_gen(self.col_positions)
@@ -4893,16 +4905,18 @@ class MainTable(tk.Canvas):
4893
4905
  add_row_positions: bool = True,
4894
4906
  push_ops: bool = True,
4895
4907
  mod_event_boxes: bool = True,
4896
- restored_state: bool = False,
4897
- ) -> EventDataDict:
4908
+ from_undo: bool = False,
4909
+ ) -> EventDataDict | None:
4910
+ if not from_undo and not try_binding(self.extra_begin_insert_cols_rc_func, event_data, "begin_add_columns"):
4911
+ return
4898
4912
  self.saved_column_widths = {}
4899
- if not restored_state and not self.all_columns_displayed:
4913
+ if not from_undo and not self.all_columns_displayed:
4900
4914
  self.displayed_columns = add_to_displayed(self.displayed_columns, columns)
4901
4915
  cws = self.get_column_widths()
4902
4916
  if column_widths and next(reversed(column_widths)) > len(cws):
4903
4917
  for i in reversed(range(len(cws), len(cws) + next(reversed(column_widths)) - len(cws))):
4904
4918
  column_widths[i] = self.PAR.ops.default_column_width
4905
- if not restored_state:
4919
+ if not from_undo:
4906
4920
  self.set_col_positions(
4907
4921
  itr=insert_items(
4908
4922
  cws,
@@ -4928,7 +4942,7 @@ class MainTable(tk.Canvas):
4928
4942
  "index": {},
4929
4943
  "row_heights": {rn: default_height for rn in range(len(self.row_positions) - 1, maxrn + 1)},
4930
4944
  }
4931
- if not restored_state:
4945
+ if not from_undo:
4932
4946
  self.set_row_positions(
4933
4947
  itr=chain(
4934
4948
  self.gen_row_heights(),
@@ -4961,9 +4975,11 @@ class MainTable(tk.Canvas):
4961
4975
  "header": header,
4962
4976
  "column_widths": column_widths,
4963
4977
  }
4978
+ if not from_undo:
4979
+ try_binding(self.extra_end_insert_cols_rc_func, event_data, "end_add_columns")
4964
4980
  return event_data
4965
4981
 
4966
- def rc_add_columns(self, event: object = None):
4982
+ def rc_add_columns(self, event: object = None) -> None:
4967
4983
  rowlen = self.equalize_data_row_lengths()
4968
4984
  selcols = sorted(self.get_selected_cols())
4969
4985
  if (
@@ -4997,8 +5013,6 @@ class MainTable(tk.Canvas):
4997
5013
  if numcols < 1:
4998
5014
  return
4999
5015
  event_data = self.new_event_dict("add_columns", state=True)
5000
- if not try_binding(self.extra_begin_insert_cols_rc_func, event_data, "begin_add_columns"):
5001
- return
5002
5016
  columns, headers, widths = self.get_args_for_add_columns(data_ins_col, displayed_ins_col, numcols)
5003
5017
  event_data = self.add_columns(
5004
5018
  columns=columns,
@@ -5006,11 +5020,11 @@ class MainTable(tk.Canvas):
5006
5020
  column_widths=widths,
5007
5021
  event_data=event_data,
5008
5022
  )
5009
- if self.undo_enabled:
5010
- self.undo_stack.append(stored_event_dict(event_data))
5011
- self.refresh()
5012
- try_binding(self.extra_end_insert_cols_rc_func, event_data, "end_add_columns")
5013
- self.sheet_modified(event_data)
5023
+ if event_data:
5024
+ if self.undo_enabled:
5025
+ self.undo_stack.append(stored_event_dict(event_data))
5026
+ self.refresh()
5027
+ self.sheet_modified(event_data)
5014
5028
 
5015
5029
  def add_rows(
5016
5030
  self,
@@ -5024,17 +5038,19 @@ class MainTable(tk.Canvas):
5024
5038
  push_ops: bool = True,
5025
5039
  tree: bool = True,
5026
5040
  mod_event_boxes: bool = True,
5027
- restored_state: bool = False,
5028
- ) -> EventDataDict:
5041
+ from_undo: bool = False,
5042
+ ) -> EventDataDict | None:
5043
+ if not from_undo and not try_binding(self.extra_begin_insert_rows_rc_func, event_data, "begin_add_rows"):
5044
+ return
5029
5045
  self.saved_row_heights = {}
5030
- if not restored_state and not self.all_rows_displayed:
5046
+ if not from_undo and not self.all_rows_displayed:
5031
5047
  self.displayed_rows = add_to_displayed(self.displayed_rows, rows)
5032
5048
  rhs = self.get_row_heights()
5033
5049
  if row_heights and next(reversed(row_heights)) > len(rhs):
5034
5050
  default_row_height = self.get_default_row_height()
5035
5051
  for i in reversed(range(len(rhs), len(rhs) + next(reversed(row_heights)) - len(rhs))):
5036
5052
  row_heights[i] = default_row_height
5037
- if not restored_state:
5053
+ if not from_undo:
5038
5054
  self.set_row_positions(
5039
5055
  itr=insert_items(
5040
5056
  rhs,
@@ -5060,7 +5076,7 @@ class MainTable(tk.Canvas):
5060
5076
  "header": {},
5061
5077
  "column_widths": {cn: default_width for cn in range(len(self.col_positions) - 1, maxcn + 1)},
5062
5078
  }
5063
- if not restored_state:
5079
+ if not from_undo:
5064
5080
  self.set_col_positions(
5065
5081
  itr=chain(
5066
5082
  self.gen_column_widths(),
@@ -5093,9 +5109,11 @@ class MainTable(tk.Canvas):
5093
5109
  }
5094
5110
  if tree and self.PAR.ops.treeview:
5095
5111
  event_data = self.RI.tree_add_rows(event_data=event_data)
5112
+ if not from_undo:
5113
+ try_binding(self.extra_end_insert_rows_rc_func, event_data, "end_add_rows")
5096
5114
  return event_data
5097
5115
 
5098
- def rc_add_rows(self, event: object = None):
5116
+ def rc_add_rows(self, event: object = None) -> None:
5099
5117
  total_data_rows = self.total_data_rows()
5100
5118
  selrows = sorted(self.get_selected_rows())
5101
5119
  if (
@@ -5129,8 +5147,6 @@ class MainTable(tk.Canvas):
5129
5147
  if numrows < 1:
5130
5148
  return
5131
5149
  event_data = self.new_event_dict("add_rows", state=True)
5132
- if not try_binding(self.extra_begin_insert_rows_rc_func, event_data, "begin_add_rows"):
5133
- return
5134
5150
  rows, index, heights = self.get_args_for_add_rows(data_ins_row, displayed_ins_row, numrows)
5135
5151
  event_data = self.add_rows(
5136
5152
  rows=rows,
@@ -5138,11 +5154,11 @@ class MainTable(tk.Canvas):
5138
5154
  row_heights=heights,
5139
5155
  event_data=event_data,
5140
5156
  )
5141
- if self.undo_enabled:
5142
- self.undo_stack.append(stored_event_dict(event_data))
5143
- self.refresh()
5144
- try_binding(self.extra_end_insert_rows_rc_func, event_data, "end_add_rows")
5145
- self.sheet_modified(event_data)
5157
+ if event_data:
5158
+ if self.undo_enabled:
5159
+ self.undo_stack.append(stored_event_dict(event_data))
5160
+ self.refresh()
5161
+ self.sheet_modified(event_data)
5146
5162
 
5147
5163
  def get_args_for_add_columns(
5148
5164
  self,
@@ -5311,7 +5327,7 @@ class MainTable(tk.Canvas):
5311
5327
  self,
5312
5328
  cols: list[int],
5313
5329
  event_data: EventDataDict | None = None,
5314
- restored_state: bool = False,
5330
+ from_undo: bool = False,
5315
5331
  ) -> EventDataDict:
5316
5332
  if not event_data:
5317
5333
  event_data = self.new_event_dict("delete_columns", state=True)
@@ -5320,7 +5336,7 @@ class MainTable(tk.Canvas):
5320
5336
  for c in reversed(cols):
5321
5337
  if len(self.col_positions) > c + 1:
5322
5338
  event_data["deleted"]["column_widths"][c] = self.col_positions[c + 1] - self.col_positions[c]
5323
- if not restored_state:
5339
+ if not from_undo:
5324
5340
  cols_set = set(cols)
5325
5341
  self.set_col_positions(
5326
5342
  itr=(width for c, width in enumerate(self.gen_column_widths()) if c not in cols_set)
@@ -5334,13 +5350,12 @@ class MainTable(tk.Canvas):
5334
5350
  data_indexes: bool = False,
5335
5351
  undo: bool = True,
5336
5352
  emit_event: bool = True,
5337
- ext: bool = False,
5338
5353
  ) -> EventDataDict:
5339
5354
  event_data = self.new_event_dict("delete_columns", state=True)
5340
5355
  if not columns:
5341
5356
  if not (columns := sorted(self.get_selected_cols())):
5342
5357
  return event_data
5343
- if not ext and not try_binding(self.extra_begin_del_cols_rc_func, event_data, "begin_delete_columns"):
5358
+ if not try_binding(self.extra_begin_del_cols_rc_func, event_data, "begin_delete_columns"):
5344
5359
  return
5345
5360
  if self.all_columns_displayed:
5346
5361
  data_columns = columns
@@ -5362,8 +5377,7 @@ class MainTable(tk.Canvas):
5362
5377
  )
5363
5378
  if undo and self.undo_enabled:
5364
5379
  self.undo_stack.append(stored_event_dict(event_data))
5365
- if not ext:
5366
- try_binding(self.extra_end_del_cols_rc_func, event_data, "end_delete_columns")
5380
+ try_binding(self.extra_end_del_cols_rc_func, event_data, "end_delete_columns")
5367
5381
  if emit_event:
5368
5382
  self.sheet_modified(event_data)
5369
5383
  self.deselect("all")
@@ -5400,7 +5414,7 @@ class MainTable(tk.Canvas):
5400
5414
  self,
5401
5415
  rows: list[int],
5402
5416
  event_data: EventDataDict | None = None,
5403
- restored_state: bool = False,
5417
+ from_undo: bool = False,
5404
5418
  ) -> EventDataDict:
5405
5419
  if not event_data:
5406
5420
  event_data = self.new_event_dict("delete_rows", state=True)
@@ -5409,7 +5423,7 @@ class MainTable(tk.Canvas):
5409
5423
  for r in reversed(rows):
5410
5424
  if len(self.row_positions) > r + 1:
5411
5425
  event_data["deleted"]["row_heights"][r] = self.row_positions[r + 1] - self.row_positions[r]
5412
- if not restored_state:
5426
+ if not from_undo:
5413
5427
  rows_set = set(rows)
5414
5428
  self.set_row_positions(
5415
5429
  itr=(height for r, height in enumerate(self.gen_row_heights()) if r not in rows_set)
@@ -5423,13 +5437,12 @@ class MainTable(tk.Canvas):
5423
5437
  data_indexes: bool = False,
5424
5438
  undo: bool = True,
5425
5439
  emit_event: bool = True,
5426
- ext: bool = False,
5427
5440
  ) -> EventDataDict:
5428
5441
  event_data = self.new_event_dict("delete_rows", state=True)
5429
5442
  if not rows:
5430
5443
  if not (rows := sorted(self.get_selected_rows())):
5431
5444
  return
5432
- if not ext and not try_binding(self.extra_begin_del_rows_rc_func, event_data, "begin_delete_rows"):
5445
+ if not try_binding(self.extra_begin_del_rows_rc_func, event_data, "begin_delete_rows"):
5433
5446
  return
5434
5447
  if self.all_rows_displayed:
5435
5448
  data_rows = rows
@@ -5462,8 +5475,7 @@ class MainTable(tk.Canvas):
5462
5475
  )
5463
5476
  if undo and self.undo_enabled:
5464
5477
  self.undo_stack.append(stored_event_dict(event_data))
5465
- if not ext:
5466
- try_binding(self.extra_end_del_rows_rc_func, event_data, "end_delete_rows")
5478
+ try_binding(self.extra_end_del_rows_rc_func, event_data, "end_delete_rows")
5467
5479
  if emit_event:
5468
5480
  self.sheet_modified(event_data)
5469
5481
  self.deselect("all")
@@ -7893,26 +7905,20 @@ class MainTable(tk.Canvas):
7893
7905
  self.data[datarn][datacn] = value
7894
7906
 
7895
7907
  def get_value_for_empty_cell(self, datarn: int, datacn: int, r_ops: bool = True, c_ops: bool = True) -> object:
7896
- if self.get_cell_kwargs(
7897
- datarn,
7898
- datacn,
7899
- key="checkbox",
7900
- cell=r_ops and c_ops,
7901
- row=r_ops,
7902
- column=c_ops,
7903
- ):
7904
- return False
7905
7908
  kwargs = self.get_cell_kwargs(
7906
7909
  datarn,
7907
7910
  datacn,
7908
- key="dropdown",
7911
+ key=None,
7909
7912
  cell=r_ops and c_ops,
7910
7913
  row=r_ops,
7911
7914
  column=c_ops,
7912
7915
  )
7913
- if kwargs and kwargs["validate_input"] and kwargs["values"]:
7916
+ if "checkbox" in kwargs:
7917
+ return False
7918
+ elif (kwargs := kwargs.get("dropdown", {})) and kwargs["validate_input"] and kwargs["values"]:
7914
7919
  return kwargs["values"][0]
7915
- return ""
7920
+ else:
7921
+ return ""
7916
7922
 
7917
7923
  def get_empty_row_seq(
7918
7924
  self,
@@ -8072,18 +8078,21 @@ class MainTable(tk.Canvas):
8072
8078
  check_readonly: bool = True,
8073
8079
  ignore_empty: bool = False,
8074
8080
  ) -> bool:
8075
- if check_readonly and self.get_cell_kwargs(datarn, datacn, key="readonly"):
8081
+ kwargs = self.get_cell_kwargs(datarn, datacn, key=None)
8082
+ if check_readonly and "readonly" in kwargs:
8076
8083
  return False
8077
- if self.get_cell_kwargs(datarn, datacn, key="format"):
8084
+ elif "format" in kwargs:
8078
8085
  return True
8079
- if self.cell_equal_to(datarn, datacn, value, ignore_empty=ignore_empty):
8086
+ elif self.cell_equal_to(datarn, datacn, value, ignore_empty=ignore_empty):
8080
8087
  return False
8081
- kwargs = self.get_cell_kwargs(datarn, datacn, key="dropdown")
8082
- if kwargs and kwargs["validate_input"] and value not in kwargs["values"]:
8088
+ elif (
8089
+ (dropdown := kwargs.get("dropdown", {})) and dropdown["validate_input"] and value not in dropdown["values"]
8090
+ ):
8083
8091
  return False
8084
- if self.get_cell_kwargs(datarn, datacn, key="checkbox"):
8092
+ elif "checkbox" in kwargs:
8085
8093
  return is_bool_like(value)
8086
- return True
8094
+ else:
8095
+ return True
8087
8096
 
8088
8097
  def cell_equal_to(self, datarn: int, datacn: int, value: object, ignore_empty: bool = False, **kwargs) -> bool:
8089
8098
  v = self.get_cell_data(datarn, datacn)
@@ -8118,18 +8127,21 @@ class MainTable(tk.Canvas):
8118
8127
  self,
8119
8128
  datarn: int,
8120
8129
  datacn: int,
8121
- key: Hashable = "format",
8130
+ key: Hashable | None = "format",
8122
8131
  cell: bool = True,
8123
8132
  row: bool = True,
8124
8133
  column: bool = True,
8125
8134
  ) -> dict:
8126
- if cell and (datarn, datacn) in self.cell_options and key in self.cell_options[(datarn, datacn)]:
8127
- return self.cell_options[(datarn, datacn)][key]
8128
- if row and datarn in self.row_options and key in self.row_options[datarn]:
8129
- return self.row_options[datarn][key]
8130
- if column and datacn in self.col_options and key in self.col_options[datacn]:
8131
- return self.col_options[datacn][key]
8132
- return {}
8135
+ if cell and (datarn, datacn) in self.cell_options:
8136
+ return (
8137
+ self.cell_options[(datarn, datacn)] if key is None else self.cell_options[(datarn, datacn)].get(key, {})
8138
+ )
8139
+ elif row and datarn in self.row_options:
8140
+ return self.row_options[datarn] if key is None else self.row_options[datarn].get(key, {})
8141
+ elif column and datacn in self.col_options:
8142
+ return self.col_options[datacn] if key is None else self.col_options[datacn].get(key, {})
8143
+ else:
8144
+ return {}
8133
8145
 
8134
8146
  def datacn(self, c: int) -> int:
8135
8147
  return c if self.all_columns_displayed else self.displayed_columns[c]
tksheet/row_index.py CHANGED
@@ -19,7 +19,6 @@ from .constants import (
19
19
  )
20
20
  from .formatters import is_bool_like, try_to_bool
21
21
  from .functions import (
22
- consecutive_chunks,
23
22
  consecutive_ranges,
24
23
  del_placeholder_dict_key,
25
24
  event_dict,
@@ -686,10 +685,10 @@ class RowIndex(tk.Canvas):
686
685
  tag="move_rows",
687
686
  )
688
687
  self.MT.create_resize_line(x1, ypos, x2, ypos, width=3, fill=self.ops.drag_and_drop_bg, tag="move_rows")
689
- for chunk in consecutive_chunks(rows):
688
+ for boxst, boxend in consecutive_ranges(rows):
690
689
  self.MT.show_ctrl_outline(
691
- start_cell=(0, chunk[0]),
692
- end_cell=(len(self.MT.col_positions) - 1, chunk[-1] + 1),
690
+ start_cell=(0, boxst),
691
+ end_cell=(len(self.MT.col_positions) - 1, boxend),
693
692
  dash=(),
694
693
  outline=self.ops.drag_and_drop_bg,
695
694
  delete_on_timer=False,
@@ -901,6 +900,8 @@ class RowIndex(tk.Canvas):
901
900
  rows = list(range(0, len(self.MT.row_positions) - 1))
902
901
  event_data = self.MT.new_event_dict("edit_table")
903
902
  try_binding(self.MT.extra_begin_sort_cells_func, event_data)
903
+ if key is None:
904
+ key = self.PAR.ops.sort_key
904
905
  for r in rows:
905
906
  datarn = self.MT.datarn(r)
906
907
  for c, val in enumerate(sort_row(self.MT.data[datarn], reverse=reverse, key=key)):
@@ -944,6 +945,8 @@ class RowIndex(tk.Canvas):
944
945
  return event_data
945
946
  row = self.MT.selected.row
946
947
  if try_binding(self.ri_extra_begin_sort_cols_func, event_data, "begin_move_columns"):
948
+ if key is None:
949
+ key = self.PAR.ops.sort_key
947
950
  sorted_indices, data_new_idxs = sort_columns_by_row(self.MT.data, row=row, reverse=reverse, key=key)
948
951
  disp_new_idxs = {}
949
952
  if self.MT.all_columns_displayed:
@@ -2425,16 +2428,17 @@ class RowIndex(tk.Canvas):
2425
2428
  self.MT._row_index[datarn] = value
2426
2429
 
2427
2430
  def input_valid_for_cell(self, datarn: int, value: object, check_readonly: bool = True) -> bool:
2428
- if check_readonly and self.get_cell_kwargs(datarn, key="readonly"):
2431
+ kwargs = self.get_cell_kwargs(datarn, key=None)
2432
+ if check_readonly and "readonly" in kwargs:
2429
2433
  return False
2430
- if self.get_cell_kwargs(datarn, key="checkbox"):
2434
+ elif "checkbox" in kwargs:
2431
2435
  return is_bool_like(value)
2432
- if self.cell_equal_to(datarn, value):
2436
+ elif self.cell_equal_to(datarn, value):
2433
2437
  return False
2434
- kwargs = self.get_cell_kwargs(datarn, key="dropdown")
2435
- if kwargs and kwargs["validate_input"] and value not in kwargs["values"]:
2438
+ elif (kwargs := kwargs.get("dropdown", {})) and kwargs["validate_input"] and value not in kwargs["values"]:
2436
2439
  return False
2437
- return True
2440
+ else:
2441
+ return True
2438
2442
 
2439
2443
  def cell_equal_to(self, datarn: int, value: object) -> bool:
2440
2444
  self.fix_index(datarn)
@@ -2496,12 +2500,13 @@ class RowIndex(tk.Canvas):
2496
2500
  if self.ops.treeview:
2497
2501
  iid = self.new_iid()
2498
2502
  return Node(text=iid, iid=iid, parent=self.get_row_parent(datarn))
2499
- if self.get_cell_kwargs(datarn, key="checkbox", cell=r_ops):
2503
+ kwargs = self.get_cell_kwargs(datarn, key=None, cell=r_ops)
2504
+ if "checkbox" in kwargs:
2500
2505
  return False
2501
- kwargs = self.get_cell_kwargs(datarn, key="dropdown", cell=r_ops)
2502
- if kwargs and kwargs["validate_input"] and kwargs["values"]:
2506
+ elif (kwargs := kwargs.get("dropdown", {})) and kwargs["validate_input"] and kwargs["values"]:
2503
2507
  return kwargs["values"][0]
2504
- return ""
2508
+ else:
2509
+ return ""
2505
2510
 
2506
2511
  def get_empty_index_seq(self, end: int, start: int = 0, r_ops: bool = True) -> list[object]:
2507
2512
  return [self.get_value_for_empty_cell(datarn, r_ops=r_ops) for datarn in range(start, end)]
@@ -2568,10 +2573,11 @@ class RowIndex(tk.Canvas):
2568
2573
  if redraw:
2569
2574
  self.MT.refresh()
2570
2575
 
2571
- def get_cell_kwargs(self, datarn: int, key: Hashable = "dropdown", cell: bool = True) -> dict:
2572
- if cell and datarn in self.cell_options and key in self.cell_options[datarn]:
2573
- return self.cell_options[datarn][key]
2574
- return {}
2576
+ def get_cell_kwargs(self, datarn: int, key: Hashable | None = "dropdown", cell: bool = True) -> dict:
2577
+ if cell and datarn in self.cell_options:
2578
+ return self.cell_options[datarn] if key is None else self.cell_options[datarn].get(key, {})
2579
+ else:
2580
+ return {}
2575
2581
 
2576
2582
  # Treeview Mode
2577
2583
 
@@ -2672,25 +2678,33 @@ class RowIndex(tk.Canvas):
2672
2678
  new_parent = node_change[1]
2673
2679
  move_to_index = node_change[2]
2674
2680
  if new_parent:
2675
- move_to_index = (
2676
- move_to_index if isinstance(move_to_index, int) else len(self.tree[new_parent].children)
2677
- )
2678
- move_to_row = self.tree_rns[new_parent] + max(
2679
- 0, min(move_to_index, len(self.tree[new_parent].children))
2680
- )
2681
+ if isinstance(move_to_index, int):
2682
+ move_to_index = min(move_to_index, len(self.tree[new_parent].children))
2683
+ else:
2684
+ move_to_index = len(self.tree[new_parent].children)
2685
+ move_to_row = self.tree_rns[new_parent]
2686
+ if new_parent == self.tree[item].parent:
2687
+ move_to_index += 1
2688
+ for i, ciid in enumerate(self.tree[new_parent].children):
2689
+ if i == move_to_index:
2690
+ break
2691
+ move_to_row += sum(1 for _ in self.get_iid_descendants(ciid)) + 1
2692
+ insert_row = move_to_row + 1
2681
2693
  else:
2682
2694
  num_top_nodes = sum(1 for _ in self.gen_top_nodes())
2683
2695
  if move_to_index is None:
2684
2696
  move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
2685
2697
  move_to_index = num_top_nodes
2698
+ insert_row = move_to_row
2686
2699
  else:
2687
2700
  move_to_row = self.PAR.top_index_row(move_to_index)
2701
+ insert_row = move_to_row
2688
2702
  if move_to_row is None:
2689
2703
  move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
2690
2704
  move_to_index = num_top_nodes
2705
+ insert_row = move_to_row + 1
2691
2706
 
2692
2707
  move_to_iid = self.MT._row_index[move_to_row].iid
2693
- insert_row = move_to_row + 1
2694
2708
  disp_insert_row = None
2695
2709
 
2696
2710
  else:
@@ -2734,10 +2748,10 @@ class RowIndex(tk.Canvas):
2734
2748
  event_data["moved"]["rows"]["displayed"] = {}
2735
2749
  if new_loc_is_displayed:
2736
2750
  if disp_insert_row is None:
2737
- if new_parent == self.tree[item].parent:
2751
+ if new_parent or insert_row > move_to_row:
2738
2752
  disp_insert_row = self.MT.disprn(self.tree_rns[move_to_iid]) + 1
2739
2753
  else:
2740
- disp_insert_row = self.MT.disprn(self.tree_rns[move_to_iid]) + 1
2754
+ disp_insert_row = self.MT.disprn(self.tree_rns[move_to_iid])
2741
2755
  if (disp_from_row := self.MT.try_disprn(self.tree_rns[item])) is not None:
2742
2756
  event_data["moved"]["rows"]["displayed"] = {disp_from_row: disp_insert_row}
2743
2757
  else:
@@ -2757,7 +2771,6 @@ class RowIndex(tk.Canvas):
2757
2771
  index=move_to_index,
2758
2772
  )
2759
2773
  move_to_index += 1
2760
-
2761
2774
  event_data["moved"]["rows"]["data"] = get_new_indexes(
2762
2775
  insert_row,
2763
2776
  event_data["moved"]["rows"]["data"],
@@ -2783,7 +2796,6 @@ class RowIndex(tk.Canvas):
2783
2796
  if not undo_modification and data_new_idxs:
2784
2797
  if new_parent and (not self.PAR.item_displayed(new_parent) or new_parent not in self.tree_open_ids):
2785
2798
  self.PAR.hide_rows(set(data_new_idxs.values()), data_indexes=True)
2786
-
2787
2799
  if new_loc_is_displayed:
2788
2800
  self.PAR.show_rows(
2789
2801
  (r for r in data_new_idxs.values() if self.ancestors_all_open(self.MT._row_index[r].iid))
@@ -2960,9 +2972,7 @@ class RowIndex(tk.Canvas):
2960
2972
  def move_pid_causes_recursive_loop(self, to_move_iid: str, move_to_parent: str) -> bool:
2961
2973
  # if the parent the item is being moved under is one of the item's descendants
2962
2974
  # then it is a recursive loop
2963
- return to_move_iid == move_to_parent or any(
2964
- move_to_parent == diid for diid in self.get_iid_descendants(to_move_iid)
2965
- )
2975
+ return any(move_to_parent == diid for diid in self.get_iid_descendants(to_move_iid))
2966
2976
 
2967
2977
  def tree_build(
2968
2978
  self,