tksheet 7.5.8__tar.gz → 7.5.9__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 (28) hide show
  1. {tksheet-7.5.8/tksheet.egg-info → tksheet-7.5.9}/PKG-INFO +1 -1
  2. {tksheet-7.5.8 → tksheet-7.5.9}/pyproject.toml +1 -1
  3. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/__init__.py +1 -1
  4. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/functions.py +11 -0
  5. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/main_table.py +5 -2
  6. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/row_index.py +46 -66
  7. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/sheet.py +41 -11
  8. {tksheet-7.5.8 → tksheet-7.5.9/tksheet.egg-info}/PKG-INFO +1 -1
  9. {tksheet-7.5.8 → tksheet-7.5.9}/LICENSE.txt +0 -0
  10. {tksheet-7.5.8 → tksheet-7.5.9}/README.md +0 -0
  11. {tksheet-7.5.8 → tksheet-7.5.9}/setup.cfg +0 -0
  12. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/colors.py +0 -0
  13. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/column_headers.py +0 -0
  14. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/constants.py +0 -0
  15. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/find_window.py +0 -0
  16. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/formatters.py +0 -0
  17. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/menus.py +0 -0
  18. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/other_classes.py +0 -0
  19. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/sheet_options.py +0 -0
  20. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/sorting.py +0 -0
  21. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/text_editor.py +0 -0
  22. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/themes.py +0 -0
  23. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/tksheet_types.py +0 -0
  24. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/tooltip.py +0 -0
  25. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet/top_left_rectangle.py +0 -0
  26. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet.egg-info/SOURCES.txt +0 -0
  27. {tksheet-7.5.8 → tksheet-7.5.9}/tksheet.egg-info/dependency_links.txt +0 -0
  28. {tksheet-7.5.8 → tksheet-7.5.9}/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.8
3
+ Version: 7.5.9
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.8"
9
+ version = "7.5.9"
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.8"
7
+ __version__ = "7.5.9"
8
8
 
9
9
  from .colors import (
10
10
  color_map,
@@ -835,6 +835,17 @@ def move_elements_to(
835
835
  )
836
836
 
837
837
 
838
+ def remove_duplicates_outside_section(strings: list[str], section_start: int, section_size: int) -> list[str]:
839
+ if section_start == 0 and section_size >= len(strings):
840
+ return strings
841
+
842
+ section_end = section_start + section_size
843
+ section_set = set(strings[section_start:section_end])
844
+ print(section_set, section_start, section_size)
845
+
846
+ return [s for i, s in enumerate(strings) if (section_start <= i < section_end) or (s not in section_set)]
847
+
848
+
838
849
  def get_new_indexes(
839
850
  move_to: int,
840
851
  to_move: Iterable[int],
@@ -1805,7 +1805,7 @@ class MainTable(tk.Canvas):
1805
1805
  create_selections: bool = True,
1806
1806
  event_data: EventDataDict | None = None,
1807
1807
  undo_modification: EventDataDict | None = None,
1808
- node_change: None | tuple[str, str, int] = None,
1808
+ node_change: None | dict = None,
1809
1809
  manage_tree: bool = True,
1810
1810
  ) -> tuple[dict[int, int], dict[int, int], EventDataDict]:
1811
1811
  self.saved_row_heights = {}
@@ -1965,7 +1965,10 @@ class MainTable(tk.Canvas):
1965
1965
  # finally, change the span coords
1966
1966
  span["from_r"], span["upto_r"] = newfrom, newupto
1967
1967
 
1968
- if (not self.PAR.ops.treeview or not undo_modification) and (move_heights and disp_new_idxs):
1968
+ if not undo_modification and create_selections and self.PAR.ops.treeview:
1969
+ self.PAR.selection_set(*[self._row_index[k].iid for k in data_new_idxs.values()])
1970
+
1971
+ elif not undo_modification and move_heights and disp_new_idxs:
1969
1972
  self.set_row_positions(
1970
1973
  itr=move_elements_by_mapping_gen(
1971
1974
  self.get_row_heights(),
@@ -35,6 +35,7 @@ from .functions import (
35
35
  num2alpha,
36
36
  push_displayed,
37
37
  recursive_bind,
38
+ remove_duplicates_outside_section,
38
39
  rounded_box_coords,
39
40
  safe_copy,
40
41
  stored_event_dict,
@@ -884,7 +885,7 @@ class RowIndex(tk.Canvas):
884
885
  elif (iid := self.event_over_tree_arrow(r, canvasy, event.x)) is not None:
885
886
  if self.MT.selection_boxes:
886
887
  self.select_row(r, ext=True, redraw=False)
887
- self.PAR.item(iid, open_=iid not in self.tree_open_ids)
888
+ self.PAR.item(iid, open_=iid not in self.tree_open_ids, undo=False)
888
889
  else:
889
890
  self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
890
891
  self.b1_pressed_loc = None
@@ -2790,6 +2791,14 @@ class RowIndex(tk.Canvas):
2790
2791
 
2791
2792
  return event_data
2792
2793
 
2794
+ def remove_descendants(self, iids: set[str]) -> tuple[list[int], set[str]]:
2795
+ return (
2796
+ sorted(
2797
+ self.rns[iid] for iid in iids if not any(ancestor in iids for ancestor in self.get_iid_ancestors(iid))
2798
+ ),
2799
+ iids,
2800
+ )
2801
+
2793
2802
  def move_rows_mod_nodes(
2794
2803
  self,
2795
2804
  data_new_idxs: dict[int, int],
@@ -2798,7 +2807,7 @@ class RowIndex(tk.Canvas):
2798
2807
  maxidx: int,
2799
2808
  event_data: EventDataDict,
2800
2809
  undo_modification: EventDataDict | None = None,
2801
- node_change: tuple[str, str, int] | None = None,
2810
+ node_change: dict | None = None,
2802
2811
  ) -> Generator[tuple[dict[int, int], dict[int, int], dict[str, int], EventDataDict]] | None:
2803
2812
  # data_new_idxs is {old: new, old: new}
2804
2813
  # data_old_idxs is {new: old, new: old}
@@ -2812,97 +2821,84 @@ class RowIndex(tk.Canvas):
2812
2821
 
2813
2822
  elif event_data["moved"]["rows"]:
2814
2823
  if node_change:
2815
- item = node_change[0]
2816
- moved_rows = [self.rns[item]]
2817
- new_parent = node_change[1]
2818
- move_to_index = node_change[2]
2819
- # new parent exists
2824
+ moved_rows, iids = self.remove_descendants(node_change["iids"])
2825
+ new_parent = node_change["new_par"]
2826
+ move_to_index = node_change["index"]
2820
2827
  if new_parent:
2821
2828
  new_par_cn = self.iid_children(new_parent)
2822
- # determine index
2829
+ len_new_par_cn = len(new_par_cn)
2823
2830
  if isinstance(move_to_index, int):
2824
- move_to_index = min(move_to_index, len(new_par_cn))
2831
+ move_to_index = min(move_to_index, len_new_par_cn)
2825
2832
  else:
2826
- move_to_index = len(new_par_cn)
2827
- # determine insert row
2833
+ move_to_index = len_new_par_cn
2828
2834
  if not new_par_cn:
2829
2835
  insert_row = self.rns[new_parent] + 1
2830
- elif move_to_index >= len(new_par_cn):
2836
+ elif move_to_index >= len_new_par_cn:
2831
2837
  insert_row = self.rns[new_par_cn[-1]] + self.num_descendants(new_par_cn[-1]) + 1
2832
- elif new_parent == self.iid_parent(item):
2833
- if move_to_index <= self.PAR.index(item):
2834
- # Insert before the sibling at move_to_index
2835
- insert_row = self.rns[new_par_cn[move_to_index]]
2836
- else:
2837
- # Insert after the sibling at move_to_index
2838
- insert_row = self.rns[new_par_cn[move_to_index]]
2839
- insert_row += 1 + self.num_descendants(new_par_cn[move_to_index])
2840
2838
  else:
2839
+ # To get the ids to the proper index and insert row -
2840
+ # For every iid that is being moved under the same parent but to an
2841
+ # index further along we have to adjust the insert row and move to index
2841
2842
  insert_row = self.rns[new_par_cn[move_to_index]]
2842
- # no new parent
2843
+ for iid in iids:
2844
+ if new_parent == self.iid_parent(iid) and move_to_index > self.PAR.index(iid):
2845
+ insert_row += 1 + self.num_descendants(new_par_cn[move_to_index])
2846
+ move_to_index += 1
2847
+ if move_to_index >= len_new_par_cn:
2848
+ break
2843
2849
  else:
2844
- # determine index
2845
2850
  if isinstance(move_to_index, int):
2846
2851
  move_to_index = min(move_to_index, sum(1 for _ in self.gen_top_nodes()))
2847
2852
  else:
2848
2853
  move_to_index = sum(1 for _ in self.gen_top_nodes())
2849
- # determine insert row
2850
2854
  insert_row = self.PAR._get_id_insert_row(move_to_index, new_parent)
2851
2855
  else:
2852
- # remove any descendants
2853
- iids = {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
2854
- moved_rows = sorted(
2855
- self.rns[iid]
2856
- for iid in iids
2857
- if not any(ancestor in iids for ancestor in self.get_iid_ancestors(iid))
2856
+ moved_rows, iids = self.remove_descendants(
2857
+ {self.MT._row_index[r].iid for r in event_data["moved"]["rows"]["data"]}
2858
2858
  )
2859
- item = self.MT._row_index[moved_rows[0]].iid
2860
2859
  if isinstance(event_data.value, int):
2861
2860
  if event_data.value >= len(self.MT.displayed_rows):
2862
2861
  insert_row = len(self.MT._row_index)
2863
2862
  else:
2864
2863
  insert_row = self.MT.datarn(event_data.value)
2865
2864
  move_to_iid = self.MT._row_index[min(insert_row, len(self.MT._row_index) - 1)].iid
2866
-
2867
2865
  else:
2868
2866
  min_from = min(event_data["moved"]["rows"]["data"])
2869
- # max_from = max(event_data.moved.rows)
2870
2867
  min_to = min(event_data["moved"]["rows"]["data"].values())
2871
2868
  max_to = max(event_data["moved"]["rows"]["data"].values())
2872
2869
  insert_row = max_to if min_from <= min_to else min_to
2873
2870
  move_to_iid = self.MT._row_index[insert_row].iid
2874
-
2875
2871
  move_to_index = self.PAR.index(move_to_iid)
2876
2872
  new_parent = self.iid_parent(move_to_iid)
2877
-
2878
- event_data["moved"]["rows"]["data"] = {moved_rows[0]: insert_row}
2873
+ if any(
2874
+ self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows
2875
+ ):
2876
+ event_data["moved"]["rows"], data_new_idxs, data_old_idxs = {}, {}, {}
2877
+ moved_rows = []
2879
2878
 
2880
2879
  new_loc_is_displayed = not new_parent or (
2881
2880
  new_parent and new_parent in self.tree_open_ids and self.PAR.item_displayed(new_parent)
2882
2881
  )
2883
- event_data["moved"]["rows"]["displayed"] = {}
2882
+ event_data["moved"]["rows"]["displayed"], disp_new_idxs = {}, {}
2884
2883
 
2885
- if any(self.move_pid_causes_recursive_loop(self.MT._row_index[r].iid, new_parent) for r in moved_rows):
2886
- event_data["moved"]["rows"] = {}
2887
- data_new_idxs, data_old_idxs, disp_new_idxs = {}, {}, {}
2888
-
2889
- else:
2884
+ if moved_rows:
2885
+ event_data["moved"]["rows"]["data"] = {moved_rows[0]: insert_row}
2886
+ iids = []
2890
2887
  for r in moved_rows:
2891
2888
  iid = self.MT._row_index[r].iid
2892
- event_data = self.move_node(
2893
- event_data=event_data,
2894
- item=iid,
2895
- parent=new_parent,
2896
- index=move_to_index,
2889
+ event_data = self.move_node(event_data=event_data, item=iid, parent=new_parent)
2890
+ iids.append(iid)
2891
+ if new_parent:
2892
+ self.iid_node(new_parent).children[move_to_index:move_to_index] = iids
2893
+ self.iid_node(new_parent).children = remove_duplicates_outside_section(
2894
+ self.iid_children(new_parent), move_to_index, len(iids)
2897
2895
  )
2898
- move_to_index += 1
2899
2896
  event_data["moved"]["rows"]["data"] = get_new_indexes(
2900
2897
  insert_row,
2901
2898
  event_data["moved"]["rows"]["data"],
2902
2899
  )
2903
2900
  data_new_idxs = event_data["moved"]["rows"]["data"]
2904
2901
  data_old_idxs = {v: k for k, v in data_new_idxs.items()}
2905
- disp_new_idxs = event_data["moved"]["rows"]["displayed"]
2906
2902
 
2907
2903
  if data_new_idxs:
2908
2904
  self.MT.move_rows_data(data_new_idxs, data_old_idxs, maxidx)
@@ -2919,27 +2915,16 @@ class RowIndex(tk.Canvas):
2919
2915
 
2920
2916
  yield None
2921
2917
 
2922
- def move_node(
2923
- self,
2924
- event_data: EventDataDict,
2925
- item: str,
2926
- parent: str | None = None,
2927
- index: int = 0,
2928
- ) -> EventDataDict:
2918
+ def move_node(self, event_data: EventDataDict, item: str, parent: str | None = None) -> EventDataDict:
2929
2919
  # also backs up nodes
2930
2920
  if parent is None:
2931
2921
  parent = self.iid_parent(item)
2932
-
2933
2922
  item_node = self.iid_node(item)
2934
-
2935
- # new parent is an item
2936
2923
  if parent:
2937
2924
  parent_node = self.iid_node(parent)
2938
2925
  # its the same parent, we're just moving index
2939
2926
  if parent == item_node.parent:
2940
2927
  event_data = self.copy_nodes((item, parent), event_data)
2941
- parent_node.children.insert(index, parent_node.children.pop(parent_node.children.index(item)))
2942
-
2943
2928
  else:
2944
2929
  if item_node.parent:
2945
2930
  event_data = self.copy_nodes((item, item_node.parent, parent), event_data)
@@ -2947,9 +2932,6 @@ class RowIndex(tk.Canvas):
2947
2932
  event_data = self.copy_nodes((item, parent), event_data)
2948
2933
  self.remove_iid_from_parents_children(item)
2949
2934
  item_node.parent = parent_node.iid
2950
- parent_node.children.insert(index, item)
2951
-
2952
- # no new parent
2953
2935
  else:
2954
2936
  if item_node.parent:
2955
2937
  event_data = self.copy_nodes((item, item_node.parent), event_data)
@@ -2958,7 +2940,7 @@ class RowIndex(tk.Canvas):
2958
2940
  self.remove_iid_from_parents_children(item)
2959
2941
  self.MT._row_index[self.rns[item]].parent = ""
2960
2942
 
2961
- # last row in mapping is where to start from +1
2943
+ # last row in mapping + 1 is where to start from
2962
2944
  mapping = event_data["moved"]["rows"]["data"]
2963
2945
  row_ctr = next(reversed(mapping.values())) + 1
2964
2946
 
@@ -2966,13 +2948,11 @@ class RowIndex(tk.Canvas):
2966
2948
  if rn not in mapping:
2967
2949
  mapping[rn] = row_ctr
2968
2950
  row_ctr += 1
2969
-
2970
2951
  for did in self.get_iid_descendants(item):
2971
2952
  mapping[self.rns[did]] = row_ctr
2972
2953
  row_ctr += 1
2973
2954
 
2974
2955
  event_data["moved"]["rows"]["data"] = mapping
2975
-
2976
2956
  return event_data
2977
2957
 
2978
2958
  def restore_nodes(self, event_data: EventDataDict) -> None:
@@ -4980,14 +4980,6 @@ class Sheet(tk.Frame):
4980
4980
  self.del_rows(rows, data_indexes=True, undo=undo)
4981
4981
  return self.set_refresh_timer(rows)
4982
4982
 
4983
- def set_children(self, parent: str, *newchildren) -> Sheet:
4984
- """
4985
- Moves everything in '*newchildren' under 'parent'
4986
- """
4987
- for iid in unpack(newchildren):
4988
- self.move(iid, parent)
4989
- return self
4990
-
4991
4983
  def top_index_row(self, index: int) -> int:
4992
4984
  try:
4993
4985
  return next(self.RI.rns[n.iid] for i, n in enumerate(self.RI.gen_top_nodes()) if i == index)
@@ -5009,9 +5001,9 @@ class Sheet(tk.Frame):
5009
5001
  """
5010
5002
  if item not in self.RI.rns:
5011
5003
  raise ValueError(f"Item '{item}' does not exist.")
5012
- if parent and parent not in self.RI.rns:
5004
+ elif parent and parent not in self.RI.rns:
5013
5005
  raise ValueError(f"Parent '{parent}' does not exist.")
5014
- if self.RI.move_pid_causes_recursive_loop(item, parent):
5006
+ elif self.RI.move_pid_causes_recursive_loop(item, parent):
5015
5007
  raise ValueError(f"Item '{item}' causes recursive loop with parent '{parent}.")
5016
5008
  data_new_idxs, disp_new_idxs, event_data = self.MT.move_rows_adjust_options_dict(
5017
5009
  data_new_idxs={},
@@ -5022,7 +5014,45 @@ class Sheet(tk.Frame):
5022
5014
  move_heights=True,
5023
5015
  create_selections=select,
5024
5016
  event_data=None,
5025
- node_change=(item, parent, index),
5017
+ node_change={"iids": {item}, "new_par": parent, "index": index},
5018
+ )
5019
+ if undo:
5020
+ self.MT.undo_stack.append(stored_event_dict(event_data))
5021
+ self.MT.sheet_modified(event_data, emit_event=emit_event)
5022
+ self.set_refresh_timer()
5023
+ return data_new_idxs, disp_new_idxs, event_data
5024
+
5025
+ def set_children(
5026
+ self,
5027
+ parent: str,
5028
+ *newchildren: str,
5029
+ index: int | None = None,
5030
+ select: bool = True,
5031
+ undo: bool = True,
5032
+ emit_event: bool = False,
5033
+ ) -> Sheet:
5034
+ """
5035
+ Moves everything in '*newchildren' under 'parent'
5036
+ """
5037
+ if parent and parent not in self.RI.rns:
5038
+ raise ValueError(f"Parent '{parent}' does not exist.")
5039
+ iids = set()
5040
+ for iid in unpack(newchildren):
5041
+ if iid not in self.RI.rns:
5042
+ raise ValueError(f"Item '{iid}' does not exist.")
5043
+ elif self.RI.move_pid_causes_recursive_loop(iid, parent):
5044
+ raise ValueError(f"Item '{iid}' causes recursive loop with parent '{parent}.")
5045
+ iids.add(iid)
5046
+ data_new_idxs, disp_new_idxs, event_data = self.MT.move_rows_adjust_options_dict(
5047
+ data_new_idxs={},
5048
+ data_old_idxs={},
5049
+ totalrows=None,
5050
+ disp_new_idxs={},
5051
+ move_data=True,
5052
+ move_heights=True,
5053
+ create_selections=select,
5054
+ event_data=None,
5055
+ node_change={"iids": iids, "new_par": parent, "index": index},
5026
5056
  )
5027
5057
  if undo:
5028
5058
  self.MT.undo_stack.append(stored_event_dict(event_data))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tksheet
3
- Version: 7.5.8
3
+ Version: 7.5.9
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
File without changes
File without changes