tksheet 7.5.3__tar.gz → 7.5.4__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 (26) hide show
  1. {tksheet-7.5.3/tksheet.egg-info → tksheet-7.5.4}/PKG-INFO +1 -1
  2. {tksheet-7.5.3 → tksheet-7.5.4}/pyproject.toml +1 -1
  3. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/__init__.py +1 -1
  4. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/functions.py +0 -12
  5. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/main_table.py +4 -6
  6. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/other_classes.py +4 -4
  7. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/row_index.py +33 -79
  8. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/sheet.py +20 -11
  9. {tksheet-7.5.3 → tksheet-7.5.4/tksheet.egg-info}/PKG-INFO +1 -1
  10. {tksheet-7.5.3 → tksheet-7.5.4}/LICENSE.txt +0 -0
  11. {tksheet-7.5.3 → tksheet-7.5.4}/README.md +0 -0
  12. {tksheet-7.5.3 → tksheet-7.5.4}/setup.cfg +0 -0
  13. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/colors.py +0 -0
  14. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/column_headers.py +0 -0
  15. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/constants.py +0 -0
  16. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/find_window.py +0 -0
  17. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/formatters.py +0 -0
  18. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/sheet_options.py +0 -0
  19. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/sorting.py +0 -0
  20. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/text_editor.py +0 -0
  21. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/themes.py +0 -0
  22. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/tksheet_types.py +0 -0
  23. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet/top_left_rectangle.py +0 -0
  24. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet.egg-info/SOURCES.txt +0 -0
  25. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet.egg-info/dependency_links.txt +0 -0
  26. {tksheet-7.5.3 → tksheet-7.5.4}/tksheet.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tksheet
3
- Version: 7.5.3
3
+ Version: 7.5.4
4
4
  Summary: Tkinter table / sheet and treeview 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 and treeview widget"
8
8
  readme = "README.md"
9
- version = "7.5.3"
9
+ version = "7.5.4"
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.5.3"
7
+ __version__ = "7.5.4"
8
8
 
9
9
  from .colors import (
10
10
  color_map,
@@ -853,18 +853,6 @@ def insert_items(
853
853
  return seq
854
854
 
855
855
 
856
- def del_placeholder_dict_key(
857
- d: dict[Hashable, Any],
858
- k: Hashable,
859
- v: Any,
860
- p: tuple = (),
861
- ) -> dict[Hashable, Any]:
862
- if p in d:
863
- del d[p]
864
- d[k] = v
865
- return d
866
-
867
-
868
856
  def data_to_displayed_idxs(
869
857
  to_convert: list[int],
870
858
  displayed: list[int],
@@ -1967,6 +1967,7 @@ class MainTable(tk.Canvas):
1967
1967
  )
1968
1968
  else:
1969
1969
  self.recreate_all_selection_boxes()
1970
+
1970
1971
  return data_new_idxs, disp_new_idxs, event_data
1971
1972
 
1972
1973
  def get_max_row_idx(self, maxidx: int | None = None) -> int:
@@ -2117,6 +2118,7 @@ class MainTable(tk.Canvas):
2117
2118
  event_data["selection_boxes"] = modification["selection_boxes"]
2118
2119
  event_data["selected"] = modification["selected"]
2119
2120
  saved_cells = False
2121
+
2120
2122
  if modification["added"]["rows"] or modification["added"]["columns"]:
2121
2123
  event_data = self.save_cells_using_modification(modification, event_data)
2122
2124
  saved_cells = True
@@ -5629,12 +5631,8 @@ class MainTable(tk.Canvas):
5629
5631
  return {
5630
5632
  "row_positions": list(self.row_positions),
5631
5633
  "col_positions": list(self.col_positions),
5632
- "displayed_rows": int(self.displayed_rows)
5633
- if isinstance(self.displayed_rows, int)
5634
- else list(self.displayed_rows),
5635
- "displayed_columns": int(self.displayed_columns)
5636
- if isinstance(self.displayed_columns, int)
5637
- else list(self.displayed_columns),
5634
+ "displayed_rows": list(self.displayed_rows),
5635
+ "displayed_columns": list(self.displayed_columns),
5638
5636
  "all_rows_displayed": bool(self.all_rows_displayed),
5639
5637
  "saved_row_heights": dict(self.saved_row_heights),
5640
5638
  "saved_column_widths": dict(self.saved_column_widths),
@@ -481,10 +481,10 @@ class Node:
481
481
  parent: str = "",
482
482
  children: list[str] | None = None,
483
483
  ) -> None:
484
- self.text = text
485
- self.iid = iid
486
- self.parent = parent
487
- self.children = children if children else []
484
+ self.text: str = text
485
+ self.iid: str = iid
486
+ self.parent: str = parent
487
+ self.children: list[str] = children if children else []
488
488
 
489
489
 
490
490
  class StorageBase:
@@ -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 Callable, Generator, Hashable, Iterator, Sequence
6
- from contextlib import suppress
7
6
  from functools import partial
8
7
  from itertools import islice, repeat
9
8
  from math import ceil
@@ -22,7 +21,6 @@ from .formatters import is_bool_like, try_to_bool
22
21
  from .functions import (
23
22
  add_to_displayed,
24
23
  consecutive_ranges,
25
- del_placeholder_dict_key,
26
24
  event_dict,
27
25
  event_has_char_key,
28
26
  event_opens_dropdown_or_checkbox,
@@ -839,7 +837,7 @@ class RowIndex(tk.Canvas):
839
837
  move_heights=self.ops.row_drag_and_drop_perform,
840
838
  event_data=event_data,
841
839
  )
842
- if data_new_idxs and disp_new_idxs:
840
+ if data_new_idxs:
843
841
  event_data["moved"]["rows"] = {
844
842
  "data": data_new_idxs,
845
843
  "displayed": disp_new_idxs,
@@ -2675,34 +2673,38 @@ class RowIndex(tk.Canvas):
2675
2673
  moved_rows = [self.rns[item]]
2676
2674
  new_parent = node_change[1]
2677
2675
  move_to_index = node_change[2]
2676
+ # new parent exists
2678
2677
  if new_parent:
2678
+ new_par_cn = self.iid_children(new_parent)
2679
+ # determine index
2679
2680
  if isinstance(move_to_index, int):
2680
- move_to_index = min(move_to_index, len(self.iid_children(new_parent)))
2681
+ move_to_index = min(move_to_index, len(new_par_cn))
2681
2682
  else:
2682
- move_to_index = len(self.iid_children(new_parent))
2683
- move_to_row = self.rns[new_parent]
2684
- _find = move_to_index + 1 if new_parent == self.iid_parent(item) else move_to_index
2685
- move_to_row += _find + sum(
2686
- self.num_descendants(cid) for cid in islice(self.iid_children(new_parent), _find)
2687
- )
2688
- insert_row = move_to_row + 1
2683
+ move_to_index = len(new_par_cn)
2684
+ # determine insert row
2685
+ if not new_par_cn:
2686
+ insert_row = self.rns[new_parent] + 1
2687
+ elif move_to_index >= len(new_par_cn):
2688
+ insert_row = self.rns[new_par_cn[-1]] + self.num_descendants(new_par_cn[-1]) + 1
2689
+ elif new_parent == self.iid_parent(item):
2690
+ if move_to_index <= self.PAR.index(item):
2691
+ # Insert before the sibling at move_to_index
2692
+ insert_row = self.rns[new_par_cn[move_to_index]]
2693
+ else:
2694
+ # Insert after the sibling at move_to_index
2695
+ insert_row = self.rns[new_par_cn[move_to_index]]
2696
+ insert_row += 1 + self.num_descendants(new_par_cn[move_to_index])
2697
+ else:
2698
+ insert_row = self.rns[new_par_cn[move_to_index]]
2699
+ # no new parent
2689
2700
  else:
2690
- num_top_nodes = sum(1 for _ in self.gen_top_nodes())
2691
- if move_to_index is None:
2692
- move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
2693
- move_to_index = num_top_nodes
2694
- insert_row = move_to_row
2701
+ # determine index
2702
+ if isinstance(move_to_index, int):
2703
+ move_to_index = min(move_to_index, sum(1 for _ in self.gen_top_nodes()))
2695
2704
  else:
2696
- move_to_row = self.PAR.top_index_row(move_to_index)
2697
- insert_row = move_to_row
2698
- if move_to_row is None:
2699
- move_to_row = self.PAR.top_index_row(num_top_nodes - 1)
2700
- move_to_index = num_top_nodes
2701
- insert_row = move_to_row + 1
2702
-
2703
- move_to_iid = self.MT._row_index[move_to_row].iid
2704
- disp_insert_row = None
2705
-
2705
+ move_to_index = sum(1 for _ in self.gen_top_nodes())
2706
+ # determine insert row
2707
+ insert_row = self.PAR._get_id_insert_row(move_to_index, new_parent)
2706
2708
  else:
2707
2709
  iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
2708
2710
  iids_descendants = {iid: set(self.get_iid_descendants(iid)) for iid in iids}
@@ -2713,21 +2715,18 @@ class RowIndex(tk.Canvas):
2713
2715
  item = self.MT._row_index[moved_rows[0]].iid
2714
2716
 
2715
2717
  if isinstance(event_data.value, int):
2716
- disp_insert_row = event_data.value
2717
- if disp_insert_row >= len(self.MT.displayed_rows):
2718
+ if event_data.value >= len(self.MT.displayed_rows):
2718
2719
  insert_row = len(self.MT._row_index)
2719
2720
  else:
2720
- insert_row = self.MT.datarn(disp_insert_row)
2721
+ insert_row = self.MT.datarn(event_data.value)
2721
2722
  move_to_iid = self.MT._row_index[min(insert_row, len(self.MT._row_index) - 1)].iid
2722
2723
 
2723
2724
  else:
2724
- disp_insert_row = None
2725
2725
  min_from = min(event_data["moved"]["rows"]["data"])
2726
2726
  # max_from = max(event_data.moved.rows)
2727
2727
  min_to = min(event_data["moved"]["rows"]["data"].values())
2728
2728
  max_to = max(event_data["moved"]["rows"]["data"].values())
2729
2729
  insert_row = max_to if min_from <= min_to else min_to
2730
- move_to_row = insert_row
2731
2730
  move_to_iid = self.MT._row_index[insert_row].iid
2732
2731
 
2733
2732
  move_to_index = self.PAR.index(move_to_iid)
@@ -2738,19 +2737,7 @@ class RowIndex(tk.Canvas):
2738
2737
  new_loc_is_displayed = not new_parent or (
2739
2738
  new_parent and new_parent in self.tree_open_ids and self.PAR.item_displayed(new_parent)
2740
2739
  )
2741
- # deal with displayed mapping
2742
2740
  event_data["moved"]["rows"]["displayed"] = {}
2743
- with suppress(Exception):
2744
- if new_loc_is_displayed:
2745
- if disp_insert_row is None:
2746
- if new_parent or insert_row > move_to_row:
2747
- disp_insert_row = self.MT.disprn(self.rns[move_to_iid]) + 1
2748
- else:
2749
- disp_insert_row = self.MT.disprn(self.rns[move_to_iid])
2750
- if (disp_from_row := self.MT.try_disprn(self.rns[item])) is not None:
2751
- event_data["moved"]["rows"]["displayed"] = {disp_from_row: disp_insert_row}
2752
- else:
2753
- event_data["moved"]["rows"]["displayed"] = {(): disp_insert_row}
2754
2741
 
2755
2742
  if any(self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows):
2756
2743
  event_data["moved"]["rows"] = {}
@@ -2772,15 +2759,6 @@ class RowIndex(tk.Canvas):
2772
2759
  )
2773
2760
  data_new_idxs = event_data["moved"]["rows"]["data"]
2774
2761
  data_old_idxs = {v: k for k, v in data_new_idxs.items()}
2775
-
2776
- if () in event_data["moved"]["rows"]["displayed"]:
2777
- del event_data["moved"]["rows"]["displayed"][()]
2778
-
2779
- if event_data["moved"]["rows"]["displayed"]:
2780
- event_data["moved"]["rows"]["displayed"] = get_new_indexes(
2781
- disp_insert_row,
2782
- event_data["moved"]["rows"]["displayed"],
2783
- )
2784
2762
  disp_new_idxs = event_data["moved"]["rows"]["displayed"]
2785
2763
 
2786
2764
  if data_new_idxs:
@@ -2817,8 +2795,7 @@ class RowIndex(tk.Canvas):
2817
2795
  # its the same parent, we're just moving index
2818
2796
  if parent == item_node.parent:
2819
2797
  event_data = self.copy_nodes((item, parent), event_data)
2820
- pop_index = parent_node.children.index(item)
2821
- parent_node.children.insert(index, parent_node.children.pop(pop_index))
2798
+ parent_node.children.insert(index, parent_node.children.pop(parent_node.children.index(item)))
2822
2799
 
2823
2800
  else:
2824
2801
  if item_node.parent:
@@ -2842,29 +2819,16 @@ class RowIndex(tk.Canvas):
2842
2819
  mapping = event_data["moved"]["rows"]["data"]
2843
2820
  row_ctr = next(reversed(mapping.values())) + 1
2844
2821
 
2845
- if disp_mapping := event_data["moved"]["rows"]["displayed"]:
2846
- if () in disp_mapping:
2847
- disp_row_ctr = next(reversed(disp_mapping.values()))
2848
- else:
2849
- disp_row_ctr = next(reversed(disp_mapping.values())) + 1
2850
-
2851
2822
  rn = self.rns[item]
2852
2823
  if rn not in mapping:
2853
2824
  mapping[rn] = row_ctr
2854
2825
  row_ctr += 1
2855
- if disp_mapping and (disp_from := self.MT.try_disprn(rn)) is not None:
2856
- disp_mapping = del_placeholder_dict_key(disp_mapping, disp_from, disp_row_ctr)
2857
- disp_row_ctr += 1
2858
2826
 
2859
2827
  for did in self.get_iid_descendants(item):
2860
2828
  mapping[self.rns[did]] = row_ctr
2861
2829
  row_ctr += 1
2862
- if disp_mapping and (disp_from := self.MT.try_disprn(self.rns[did])) is not None:
2863
- disp_mapping = del_placeholder_dict_key(disp_mapping, disp_from, disp_row_ctr)
2864
- disp_row_ctr += 1
2865
2830
 
2866
2831
  event_data["moved"]["rows"]["data"] = mapping
2867
- event_data["moved"]["rows"]["displayed"] = disp_mapping
2868
2832
 
2869
2833
  return event_data
2870
2834
 
@@ -2872,21 +2836,11 @@ class RowIndex(tk.Canvas):
2872
2836
  for iid, node in event_data["treeview"]["nodes"].items():
2873
2837
  self.MT._row_index[self.rns[iid]] = node
2874
2838
 
2875
- def copy_node(self, item: str) -> Node:
2876
- n = self.iid_node(item)
2877
- return Node(
2878
- text=n.text,
2879
- iid=n.iid,
2880
- parent=n.parent,
2881
- children=n.children.copy(),
2882
- )
2883
-
2884
2839
  def copy_nodes(self, items: Iterator[str], event_data: EventDataDict) -> EventDataDict:
2885
- nodes = event_data["treeview"]["nodes"]
2886
2840
  for iid in items:
2887
- if iid not in nodes:
2841
+ if iid not in event_data["treeview"]["nodes"]:
2888
2842
  n = self.iid_node(iid)
2889
- nodes[iid] = Node(
2843
+ event_data["treeview"]["nodes"][iid] = Node(
2890
2844
  text=n.text,
2891
2845
  iid=n.iid,
2892
2846
  parent=n.parent,
@@ -4744,7 +4744,7 @@ class Sheet(tk.Frame):
4744
4744
  self.hide_rows(datarn, deselect_all=False, data_indexes=True)
4745
4745
  return iid
4746
4746
 
4747
- def _get_id_insert_row(self, index: int, parent: str) -> int:
4747
+ def _get_id_insert_row(self, index: int | None, parent: str) -> int:
4748
4748
  if parent:
4749
4749
  if isinstance(index, int):
4750
4750
  index = min(index, len(self.RI.iid_children(parent)))
@@ -4759,7 +4759,7 @@ class Sheet(tk.Frame):
4759
4759
  else:
4760
4760
  if isinstance(index, int):
4761
4761
  datarn = index
4762
- if index and (datarn := self.top_index_row(datarn)) is None:
4762
+ if index and (datarn := self.top_index_row(index)) is None:
4763
4763
  datarn = len(self.MT._row_index)
4764
4764
  else:
4765
4765
  datarn = len(self.MT._row_index)
@@ -4792,6 +4792,8 @@ class Sheet(tk.Frame):
4792
4792
  rns_to_add = {}
4793
4793
  for rn, r in enumerate(data, start=datarn):
4794
4794
  iid = self.RI.new_iid() if iid_column is None else r[iid_column]
4795
+ if iid in self.RI.rns:
4796
+ raise ValueError(f"iid '{iid}' already exists.")
4795
4797
  new_node = Node(
4796
4798
  r[text_column] if isinstance(text_column, int) else text_column if isinstance(text_column, str) else "",
4797
4799
  iid,
@@ -4995,11 +4997,24 @@ class Sheet(tk.Frame):
4995
4997
  raise ValueError(f"Item '{item}' does not exist.")
4996
4998
  return self.RI.iid_parent(item)
4997
4999
 
4998
- def index(self, item: str) -> int:
5000
+ def index(self, item: str, safety: bool = False) -> int:
5001
+ """
5002
+ Finds the index of an item amongst it's siblings in the
5003
+ treeview.
5004
+
5005
+ 'safety' is only necessary when the internal row number dict
5006
+ is not able to provide row numbers, e.g. when modifying the
5007
+ tree and before the action is complete.
5008
+
5009
+ When 'True' the fn uses list.index() instead.
5010
+ """
4999
5011
  if item not in self.RI.rns:
5000
5012
  raise ValueError(f"Item '{item}' does not exist.")
5001
- elif self.RI.iid_parent(item):
5002
- return self.RI.parent_node(item).children.index(item)
5013
+ elif par := self.RI.iid_parent(item):
5014
+ if not safety:
5015
+ return self.RI.rns[item] - self.RI.rns[par] - 1
5016
+ else:
5017
+ return self.RI.parent_node(item).children.index(item)
5003
5018
  else:
5004
5019
  return next(index for index, iid in enumerate(self.get_children("")) if iid == item)
5005
5020
 
@@ -6349,20 +6364,14 @@ class Sheet(tk.Frame):
6349
6364
  **{k: v["dropdown"] for k, v in self.MT.row_options.items() if "dropdown" in v},
6350
6365
  **{k: v["dropdown"] for k, v in self.MT.col_options.items() if "dropdown" in v},
6351
6366
  }
6352
- if "dropdown" in self.MT.options:
6353
- return {**d, "dropdown": self.MT.options["dropdown"]}
6354
6367
  return d
6355
6368
 
6356
6369
  def get_header_dropdowns(self) -> dict:
6357
6370
  d = {k: v["dropdown"] for k, v in self.CH.cell_options.items() if "dropdown" in v}
6358
- if "dropdown" in self.CH.options:
6359
- return {**d, "dropdown": self.CH.options["dropdown"]}
6360
6371
  return d
6361
6372
 
6362
6373
  def get_index_dropdowns(self) -> dict:
6363
6374
  d = {k: v["dropdown"] for k, v in self.RI.cell_options.items() if "dropdown" in v}
6364
- if "dropdown" in self.RI.options:
6365
- return {**d, "dropdown": self.RI.options["dropdown"]}
6366
6375
  return d
6367
6376
 
6368
6377
  def set_dropdown_values(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tksheet
3
- Version: 7.5.3
3
+ Version: 7.5.4
4
4
  Summary: Tkinter table / sheet and treeview 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
File without changes