tksheet 7.1.23__tar.gz → 7.2.0__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.1.23/tksheet.egg-info → tksheet-7.2.0}/PKG-INFO +1 -1
  2. {tksheet-7.1.23 → tksheet-7.2.0}/pyproject.toml +1 -1
  3. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/__init__.py +1 -1
  4. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/column_headers.py +5 -5
  5. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/main_table.py +88 -56
  6. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/row_index.py +20 -16
  7. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/sheet.py +64 -23
  8. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/sheet_options.py +2 -1
  9. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/text_editor.py +1 -1
  10. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/themes.py +5 -5
  11. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/top_left_rectangle.py +3 -2
  12. {tksheet-7.1.23 → tksheet-7.2.0/tksheet.egg-info}/PKG-INFO +1 -1
  13. {tksheet-7.1.23 → tksheet-7.2.0}/LICENSE.txt +0 -0
  14. {tksheet-7.1.23 → tksheet-7.2.0}/README.md +0 -0
  15. {tksheet-7.1.23 → tksheet-7.2.0}/setup.cfg +0 -0
  16. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/colors.py +0 -0
  17. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/formatters.py +0 -0
  18. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/functions.py +0 -0
  19. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/other_classes.py +0 -0
  20. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/types.py +0 -0
  21. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet/vars.py +0 -0
  22. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet.egg-info/SOURCES.txt +0 -0
  23. {tksheet-7.1.23 → tksheet-7.2.0}/tksheet.egg-info/dependency_links.txt +0 -0
  24. {tksheet-7.1.23 → tksheet-7.2.0}/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.1.23
3
+ Version: 7.2.0
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
@@ -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.1.23"
9
+ version = "7.2.0"
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.1.23"
7
+ __version__ = "7.2.0"
8
8
 
9
9
  from .colors import (
10
10
  color_map,
@@ -771,11 +771,9 @@ class ColumnHeaders(tk.Canvas):
771
771
  return False
772
772
 
773
773
  def b1_release(self, event: object) -> None:
774
- if self.being_drawn_item is not None:
775
- to_sel = self.MT.coords_and_type(self.being_drawn_item)
774
+ if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
776
775
  r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
777
776
  self.MT.hide_selection_box(self.being_drawn_item)
778
- self.being_drawn_item = None
779
777
  self.MT.set_currently_selected(
780
778
  r_to_sel,
781
779
  c_to_sel,
@@ -784,6 +782,8 @@ class ColumnHeaders(tk.Canvas):
784
782
  sel_event = self.MT.get_select_event(being_drawn_item=self.being_drawn_item)
785
783
  try_binding(self.drag_selection_binding_func, sel_event)
786
784
  self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
785
+ else:
786
+ self.being_drawn_item = None
787
787
  self.MT.bind("<MouseWheel>", self.MT.mousewheel)
788
788
  if self.width_resizing_enabled and self.rsz_w is not None and self.currently_resizing_width:
789
789
  self.currently_resizing_width = False
@@ -1607,11 +1607,11 @@ class ColumnHeaders(tk.Canvas):
1607
1607
 
1608
1608
  def get_redraw_selections(self, startc: int, endc: int) -> dict[str, set[int]]:
1609
1609
  d = defaultdict(set)
1610
- for item, box in self.MT.get_selection_items(rows=False):
1610
+ for item, box in self.MT.get_selection_items():
1611
1611
  r1, c1, r2, c2 = box.coords
1612
1612
  for c in range(startc, endc):
1613
1613
  if c1 <= c and c2 > c:
1614
- d[box.type_].add(c)
1614
+ d[box.type_ if box.type_ != "rows" else "cells"].add(c)
1615
1615
  return d
1616
1616
 
1617
1617
  def open_cell(self, event: object = None, ignore_existing_editor=False):
@@ -683,9 +683,9 @@ class MainTable(tk.Canvas):
683
683
  return event_data
684
684
 
685
685
  def ctrl_v(self, event: object = None, validation: bool = True) -> None | EventDataDict:
686
- if not self.PAR.ops.expand_sheet_if_paste_too_big and (
687
- len(self.col_positions) == 1 or len(self.row_positions) == 1
688
- ):
686
+ if not self.PAR.ops.paste_can_expand_x and len(self.col_positions) == 1:
687
+ return
688
+ if not self.PAR.ops.paste_can_expand_y and len(self.row_positions) == 1:
689
689
  return
690
690
  event_data = event_dict(
691
691
  name="edit_table",
@@ -696,7 +696,7 @@ class MainTable(tk.Canvas):
696
696
  if self.selected:
697
697
  selected_r = self.selected.row
698
698
  selected_c = self.selected.column
699
- elif not self.selected and not self.PAR.ops.expand_sheet_if_paste_too_big:
699
+ elif not self.selected and not self.PAR.ops.paste_can_expand_x and not self.PAR.ops.paste_can_expand_y:
700
700
  return
701
701
  else:
702
702
  if not self.data:
@@ -721,32 +721,31 @@ class MainTable(tk.Canvas):
721
721
  for rn, r in enumerate(data):
722
722
  if len(r) < new_data_numcols:
723
723
  data[rn] += list(repeat("", new_data_numcols - len(r)))
724
- (
725
- lastbox_r1,
726
- lastbox_c1,
727
- lastbox_r2,
728
- lastbox_c2,
729
- ) = self.selection_boxes[self.selected.fill_iid].coords
730
- lastbox_numrows = lastbox_r2 - lastbox_r1
731
- lastbox_numcols = lastbox_c2 - lastbox_c1
732
- if lastbox_numrows > new_data_numrows and not lastbox_numrows % new_data_numrows:
733
- nd = []
734
- for _ in range(int(lastbox_numrows / new_data_numrows)):
735
- nd.extend(r.copy() for r in data)
736
- data.extend(nd)
737
- new_data_numrows *= int(lastbox_numrows / new_data_numrows)
738
-
739
- if lastbox_numcols > new_data_numcols and not lastbox_numcols % new_data_numcols:
740
- for rn, r in enumerate(data):
741
- for _ in range(int(lastbox_numcols / new_data_numcols)):
742
- data[rn].extend(r.copy())
743
- new_data_numcols *= int(lastbox_numcols / new_data_numcols)
724
+ if self.selected:
725
+ (
726
+ lastbox_r1,
727
+ lastbox_c1,
728
+ lastbox_r2,
729
+ lastbox_c2,
730
+ ) = self.selection_boxes[self.selected.fill_iid].coords
731
+ lastbox_numrows = lastbox_r2 - lastbox_r1
732
+ lastbox_numcols = lastbox_c2 - lastbox_c1
733
+ if lastbox_numrows > new_data_numrows and not lastbox_numrows % new_data_numrows:
734
+ nd = []
735
+ for _ in range(int(lastbox_numrows / new_data_numrows)):
736
+ nd.extend(r.copy() for r in data)
737
+ data.extend(nd)
738
+ new_data_numrows *= int(lastbox_numrows / new_data_numrows)
739
+ if lastbox_numcols > new_data_numcols and not lastbox_numcols % new_data_numcols:
740
+ for rn, r in enumerate(data):
741
+ for _ in range(int(lastbox_numcols / new_data_numcols)):
742
+ data[rn].extend(r.copy())
743
+ new_data_numcols *= int(lastbox_numcols / new_data_numcols)
744
744
  event_data["data"] = data
745
745
  added_rows = 0
746
746
  added_cols = 0
747
747
  total_data_cols = None
748
- if self.PAR.ops.expand_sheet_if_paste_too_big:
749
- # determine number of columns and/or rows to add to sheet
748
+ if self.PAR.ops.paste_can_expand_x:
750
749
  if selected_c + new_data_numcols > len(self.col_positions) - 1:
751
750
  total_data_cols = self.equalize_data_row_lengths()
752
751
  added_cols = selected_c + new_data_numcols - len(self.col_positions) + 1
@@ -755,6 +754,7 @@ class MainTable(tk.Canvas):
755
754
  and self.PAR.ops.paste_insert_column_limit < len(self.col_positions) - 1 + added_cols
756
755
  ):
757
756
  added_cols = self.PAR.ops.paste_insert_column_limit - len(self.col_positions) - 1
757
+ if self.PAR.ops.paste_can_expand_y:
758
758
  if selected_r + new_data_numrows > len(self.row_positions) - 1:
759
759
  added_rows = selected_r + new_data_numrows - len(self.row_positions) + 1
760
760
  if (
@@ -772,6 +772,7 @@ class MainTable(tk.Canvas):
772
772
  adjusted_new_data_numrows = new_data_numrows
773
773
  selected_r_adjusted_new_data_numrows = selected_r + adjusted_new_data_numrows
774
774
  selected_c_adjusted_new_data_numcols = selected_c + adjusted_new_data_numcols
775
+ endrow = selected_r_adjusted_new_data_numrows
775
776
  boxes = {
776
777
  (
777
778
  selected_r,
@@ -807,7 +808,7 @@ class MainTable(tk.Canvas):
807
808
  value=val,
808
809
  event_data=event_data,
809
810
  )
810
- if added_rows > 0:
811
+ if added_rows:
811
812
  ctr = 0
812
813
  data_ins_row = len(self.data)
813
814
  displayed_ins_row = len(self.row_positions) - 1
@@ -817,6 +818,7 @@ class MainTable(tk.Canvas):
817
818
  data_ins_row=data_ins_row,
818
819
  displayed_ins_row=displayed_ins_row,
819
820
  numrows=added_rows,
821
+ total_data_cols=total_data_cols,
820
822
  )
821
823
  for ndr, r in zip(
822
824
  range(
@@ -851,8 +853,10 @@ class MainTable(tk.Canvas):
851
853
  row_heights=row_heights,
852
854
  event_data=event_data,
853
855
  )
854
- if added_cols > 0:
856
+ if added_cols:
855
857
  ctr = 0
858
+ if total_data_cols is None:
859
+ total_data_cols = self.total_data_cols()
856
860
  data_ins_col = total_data_cols
857
861
  displayed_ins_col = len(self.col_positions) - 1
858
862
  columns, headers, column_widths = self.get_args_for_add_columns(
@@ -860,10 +864,15 @@ class MainTable(tk.Canvas):
860
864
  displayed_ins_col=displayed_ins_col,
861
865
  numcols=added_cols,
862
866
  )
867
+ # only add the extra rows if expand_y is allowed
868
+ if self.PAR.ops.paste_can_expand_x and self.PAR.ops.paste_can_expand_y:
869
+ endrow = selected_r + new_data_numrows
870
+ else:
871
+ endrow = selected_r + adjusted_new_data_numrows
863
872
  for ndr, r in enumerate(
864
873
  range(
865
874
  selected_r,
866
- selected_r + new_data_numrows,
875
+ endrow,
867
876
  )
868
877
  ):
869
878
  for ndc, c in zip(
@@ -896,11 +905,19 @@ class MainTable(tk.Canvas):
896
905
  self.deselect("all", redraw=False)
897
906
  if event_data["cells"]["table"] or event_data["added"]["rows"] or event_data["added"]["columns"]:
898
907
  self.undo_stack.append(pickled_event_dict(event_data))
908
+ if added_rows:
909
+ selboxr = selected_r + new_data_numrows
910
+ else:
911
+ selboxr = selected_r_adjusted_new_data_numrows
912
+ if added_cols:
913
+ selboxc = selected_c + new_data_numcols
914
+ else:
915
+ selboxc = selected_c_adjusted_new_data_numcols
899
916
  self.create_selection_box(
900
917
  selected_r,
901
918
  selected_c,
902
- selected_r_adjusted_new_data_numrows,
903
- selected_c_adjusted_new_data_numcols,
919
+ selboxr,
920
+ selboxc,
904
921
  "cells",
905
922
  run_binding=True,
906
923
  )
@@ -1260,7 +1277,7 @@ class MainTable(tk.Canvas):
1260
1277
  len(self.row_positions) - 1,
1261
1278
  max(data_new_idxs.values(), default=0),
1262
1279
  )
1263
- totalrows = self.fix_data_len(totalrows)
1280
+ self.fix_data_len(totalrows)
1264
1281
  if event_data is None:
1265
1282
  event_data = event_dict(
1266
1283
  name="move_rows",
@@ -2421,7 +2438,7 @@ class MainTable(tk.Canvas):
2421
2438
  command=self.ctrl_v,
2422
2439
  **mnkwgs,
2423
2440
  )
2424
- if self.PAR.ops.expand_sheet_if_paste_too_big:
2441
+ if self.PAR.ops.paste_can_expand_x or self.PAR.ops.paste_can_expand_y:
2425
2442
  self.menu_add_command(
2426
2443
  self.empty_rc_popup_menu,
2427
2444
  label=self.PAR.ops.paste_label,
@@ -3062,11 +3079,9 @@ class MainTable(tk.Canvas):
3062
3079
  self.b1_motion(event)
3063
3080
 
3064
3081
  def b1_release(self, event=None):
3065
- if self.being_drawn_item is not None:
3066
- to_sel = self.coords_and_type(self.being_drawn_item)
3082
+ if self.being_drawn_item is not None and (to_sel := self.coords_and_type(self.being_drawn_item)):
3067
3083
  r_to_sel, c_to_sel = self.selected.row, self.selected.column
3068
3084
  self.hide_selection_box(self.being_drawn_item)
3069
- self.being_drawn_item = None
3070
3085
  self.set_currently_selected(
3071
3086
  r_to_sel,
3072
3087
  c_to_sel,
@@ -3084,6 +3099,8 @@ class MainTable(tk.Canvas):
3084
3099
  if self.drag_selection_binding_func:
3085
3100
  self.drag_selection_binding_func(sel_event)
3086
3101
  self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
3102
+ else:
3103
+ self.being_drawn_item = None
3087
3104
  if self.RI.width_resizing_enabled and self.RI.rsz_w is not None and self.RI.currently_resizing_width:
3088
3105
  self.delete_resize_lines()
3089
3106
  self.RI.delete_resize_lines()
@@ -3449,7 +3466,7 @@ class MainTable(tk.Canvas):
3449
3466
  def get_lines_cell_height(self, n, font=None):
3450
3467
  return (
3451
3468
  self.get_txt_h(
3452
- txt="\n".join("|" for lines in range(n)) if n > 1 else "|",
3469
+ txt="\n".join("|" for _ in range(n)) if n > 1 else "|",
3453
3470
  font=self.PAR.ops.table_font if font is None else font,
3454
3471
  )
3455
3472
  + 5
@@ -3467,12 +3484,20 @@ class MainTable(tk.Canvas):
3467
3484
 
3468
3485
  def get_default_row_height(self) -> int:
3469
3486
  if isinstance(self.PAR.ops.default_row_height, str):
3470
- return self.get_lines_cell_height(int(self.PAR.ops.default_row_height))
3487
+ if int(self.PAR.ops.default_row_height) == 1:
3488
+ return self.min_row_height
3489
+ else:
3490
+ return self.min_row_height + self.get_lines_cell_height(int(self.PAR.ops.default_row_height) - 1)
3471
3491
  return self.PAR.ops.default_row_height
3472
3492
 
3473
3493
  def get_default_header_height(self) -> int:
3474
3494
  if isinstance(self.PAR.ops.default_header_height, str):
3475
- return self.get_lines_cell_height(int(self.PAR.ops.default_header_height), font=self.PAR.ops.header_font)
3495
+ if int(self.PAR.ops.default_header_height) == 1:
3496
+ return self.min_header_height
3497
+ else:
3498
+ return self.min_header_height + self.get_lines_cell_height(
3499
+ int(self.PAR.ops.default_header_height) - 1, font=self.PAR.ops.header_font
3500
+ )
3476
3501
  return self.PAR.ops.default_header_height
3477
3502
 
3478
3503
  def set_table_font(self, newfont: tuple | None = None, reset_row_positions: bool = False) -> tuple[str, int, str]:
@@ -3502,8 +3527,8 @@ class MainTable(tk.Canvas):
3502
3527
  self.table_first_ln_ins = self.table_half_txt_height + 2
3503
3528
  else:
3504
3529
  self.table_first_ln_ins = self.table_half_txt_height + 3
3530
+ self.min_row_height = int(self.table_first_ln_ins * 2.25)
3505
3531
  self.table_xtra_lines_increment = int(self.table_txt_height)
3506
- self.min_row_height = self.table_txt_height + 5
3507
3532
  if self.min_row_height < 12:
3508
3533
  self.min_row_height = 12
3509
3534
  self.set_min_column_width()
@@ -3531,7 +3556,7 @@ class MainTable(tk.Canvas):
3531
3556
  else:
3532
3557
  self.header_first_ln_ins = self.header_half_txt_height + 3
3533
3558
  self.header_xtra_lines_increment = self.header_txt_height
3534
- self.min_header_height = self.header_txt_height + 5
3559
+ self.min_header_height = int(self.header_first_ln_ins * 2.25)
3535
3560
  if (
3536
3561
  isinstance(self.PAR.ops.default_header_height, int)
3537
3562
  and self.PAR.ops.default_header_height < self.min_header_height
@@ -4295,13 +4320,12 @@ class MainTable(tk.Canvas):
4295
4320
  column_widths,
4296
4321
  )
4297
4322
  )
4298
- # we're inserting so we can use indexes == len for
4299
- # fix functions, the values will go on the end
4323
+ # rn needed for indexing but cn insert
4300
4324
  maxrn = 0
4301
4325
  for cn, rowdict in reversed(columns.items()):
4302
4326
  for rn, v in rowdict.items():
4303
- if rn > len(self.data):
4304
- self.fix_data_len(rn - 1, cn - 1)
4327
+ if rn >= len(self.data):
4328
+ self.fix_data_len(rn, cn - 1)
4305
4329
  if rn > maxrn:
4306
4330
  maxrn = rn
4307
4331
  self.data[rn].insert(cn, v)
@@ -4314,7 +4338,7 @@ class MainTable(tk.Canvas):
4314
4338
  (default_row_height for i in range(len(self.row_positions) - 1, maxrn + 1)),
4315
4339
  )
4316
4340
  )
4317
- if isinstance(self._headers, list):
4341
+ if isinstance(self._headers, list) and header:
4318
4342
  self._headers = insert_items(self._headers, header, self.CH.fix_header)
4319
4343
  if push_ops:
4320
4344
  self.adjust_options_post_add_columns(
@@ -4431,6 +4455,7 @@ class MainTable(tk.Canvas):
4431
4455
  )
4432
4456
  )
4433
4457
  maxcn = 0
4458
+ # rn needed for insert but cn indexing
4434
4459
  for rn, row in reversed(rows.items()):
4435
4460
  cn = len(row) - 1
4436
4461
  if rn > len(self.data):
@@ -4438,7 +4463,7 @@ class MainTable(tk.Canvas):
4438
4463
  self.data.insert(rn, row)
4439
4464
  if cn > maxcn:
4440
4465
  maxcn = cn
4441
- if isinstance(self._row_index, list):
4466
+ if isinstance(self._row_index, list) and index:
4442
4467
  self._row_index = insert_items(self._row_index, index, self.RI.fix_index)
4443
4468
  # if not hiding columns then we can extend col positions if necessary
4444
4469
  if add_col_positions and self.all_columns_displayed and maxcn + 1 > len(self.col_positions) - 1:
@@ -4540,16 +4565,16 @@ class MainTable(tk.Canvas):
4540
4565
  datacn: column[0]
4541
4566
  for datacn, column in zip(reversed(range(data_ins_col, data_ins_col + numcols)), reversed(columns))
4542
4567
  }
4543
- elif columns:
4568
+ else:
4544
4569
  header_data = {
4545
4570
  datacn: self.CH.get_value_for_empty_cell(datacn, c_ops=False)
4546
4571
  for datacn in reversed(range(data_ins_col, data_ins_col + numcols))
4547
4572
  }
4548
4573
  if columns is None:
4574
+ rowrange = len(self.data) if self.data else 1
4549
4575
  columns = {
4550
4576
  datacn: {
4551
- datarn: self.get_value_for_empty_cell(datarn, datacn, c_ops=False)
4552
- for datarn in range(len(self.data))
4577
+ datarn: self.get_value_for_empty_cell(datarn, datacn, c_ops=False) for datarn in range(rowrange)
4553
4578
  }
4554
4579
  for datacn in reversed(range(data_ins_col, data_ins_col + numcols))
4555
4580
  }
@@ -4591,7 +4616,7 @@ class MainTable(tk.Canvas):
4591
4616
  datarn: v[0]
4592
4617
  for datarn, v in zip(reversed(range(data_ins_row, data_ins_row + numrows)), reversed(rows))
4593
4618
  }
4594
- elif rows:
4619
+ else:
4595
4620
  index_data = {
4596
4621
  datarn: self.RI.get_value_for_empty_cell(datarn, r_ops=False)
4597
4622
  for datarn in reversed(range(data_ins_row, data_ins_row + numrows))
@@ -4599,8 +4624,9 @@ class MainTable(tk.Canvas):
4599
4624
  if rows is None:
4600
4625
  if total_data_cols is None:
4601
4626
  total_data_cols = self.total_data_cols()
4627
+ colrange = total_data_cols if total_data_cols else 1
4602
4628
  rows = {
4603
- datarn: [self.get_value_for_empty_cell(datarn, c, c_ops=False) for c in range(total_data_cols)]
4629
+ datarn: [self.get_value_for_empty_cell(datarn, c, c_ops=False) for c in range(colrange)]
4604
4630
  for datarn in reversed(range(data_ins_row, data_ins_row + numrows))
4605
4631
  }
4606
4632
  else:
@@ -4971,7 +4997,7 @@ class MainTable(tk.Canvas):
4971
4997
  total_data_cols = at_least_cols
4972
4998
  total_data_cols = max(total_data_cols, len(self.col_positions) - 1)
4973
4999
  if not isinstance(self._headers, int) and include_header and total_data_cols > len(self._headers):
4974
- self.CH.fix_header(total_data_cols)
5000
+ self.CH.fix_header(total_data_cols - 1)
4975
5001
  for rn, r in enumerate(self.data):
4976
5002
  if total_data_cols > (lnr := len(r)):
4977
5003
  r += self.get_empty_row_seq(rn, end=total_data_cols, start=lnr)
@@ -5363,6 +5389,10 @@ class MainTable(tk.Canvas):
5363
5389
  if resized_cols or resized_rows or changed_w:
5364
5390
  self.recreate_all_selection_boxes()
5365
5391
  if changed_w:
5392
+ self.update_idletasks()
5393
+ self.RI.update_idletasks()
5394
+ self.CH.update_idletasks()
5395
+ self.TL.update_idletasks()
5366
5396
  return False
5367
5397
  self.hidd_text.update(self.disp_text)
5368
5398
  self.disp_text = {}
@@ -5916,6 +5946,8 @@ class MainTable(tk.Canvas):
5916
5946
  if self.selected.fill_iid == item:
5917
5947
  self.hide_selected()
5918
5948
  self.set_current_to_last()
5949
+ if item == self.being_drawn_item:
5950
+ self.being_drawn_item = None
5919
5951
  return True
5920
5952
 
5921
5953
  def hide_selected(self) -> None:
@@ -6978,9 +7010,9 @@ class MainTable(tk.Canvas):
6978
7010
  return self.mouseclick_outside_editor_or_dropdown()
6979
7011
 
6980
7012
  def hide_dropdown_editor_all_canvases(self):
6981
- self.hide_text_editor_and_dropdown()
6982
- self.RI.hide_text_editor_and_dropdown()
6983
- self.CH.hide_text_editor_and_dropdown()
7013
+ self.hide_text_editor_and_dropdown(redraw=False)
7014
+ self.RI.hide_text_editor_and_dropdown(redraw=False)
7015
+ self.CH.hide_text_editor_and_dropdown(redraw=False)
6984
7016
 
6985
7017
  def hide_dropdown_window(self) -> None:
6986
7018
  if self.dropdown.open:
@@ -173,14 +173,14 @@ class RowIndex(tk.Canvas):
173
173
  self.MT.row_positions = [0]
174
174
  self.MT.saved_row_heights = {}
175
175
 
176
- def set_width(self, new_width: int, set_TL: bool = False) -> None:
176
+ def set_width(self, new_width: int, set_TL: bool = False, recreate_selection_boxes: bool = True) -> None:
177
177
  self.current_width = new_width
178
178
  try:
179
179
  self.config(width=new_width)
180
180
  except Exception:
181
181
  return
182
182
  if set_TL:
183
- self.TL.set_dimensions(new_w=new_width)
183
+ self.TL.set_dimensions(new_w=new_width, recreate_selection_boxes=recreate_selection_boxes)
184
184
 
185
185
  def rc(self, event: object) -> None:
186
186
  self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
@@ -772,11 +772,9 @@ class RowIndex(tk.Canvas):
772
772
  return False
773
773
 
774
774
  def b1_release(self, event: object) -> None:
775
- if self.being_drawn_item is not None:
776
- to_sel = self.MT.coords_and_type(self.being_drawn_item)
775
+ if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
777
776
  r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
778
777
  self.MT.hide_selection_box(self.being_drawn_item)
779
- self.being_drawn_item = None
780
778
  self.MT.set_currently_selected(
781
779
  r_to_sel,
782
780
  c_to_sel,
@@ -785,6 +783,8 @@ class RowIndex(tk.Canvas):
785
783
  sel_event = self.MT.get_select_event(being_drawn_item=self.being_drawn_item)
786
784
  try_binding(self.drag_selection_binding_func, sel_event)
787
785
  self.PAR.emit_event("<<SheetSelect>>", data=sel_event)
786
+ else:
787
+ self.being_drawn_item = None
788
788
  self.MT.bind("<MouseWheel>", self.MT.mousewheel)
789
789
  if self.height_resizing_enabled and self.rsz_h is not None and self.currently_resizing_height:
790
790
  self.currently_resizing_height = False
@@ -1030,7 +1030,7 @@ class RowIndex(tk.Canvas):
1030
1030
  align = self.align
1031
1031
  if align == "w":
1032
1032
  w += self.MT.index_txt_height
1033
- w += self.get_treeview_indent(self.MT._row_index[datarn].iid) + 4
1033
+ w += self.get_treeview_indent(self.MT._row_index[datarn].iid) + 5
1034
1034
  return w, h
1035
1035
 
1036
1036
  def set_row_height(
@@ -1205,8 +1205,8 @@ class RowIndex(tk.Canvas):
1205
1205
  new_w = None
1206
1206
  if new_w is not None and (sheet_w_x := floor(self.PAR.winfo_width() * 0.7)) < new_w:
1207
1207
  new_w = sheet_w_x
1208
- if new_w and (self.current_width - new_w > 15 or new_w - self.current_width > 3):
1209
- self.set_width(new_w, set_TL=True)
1208
+ if new_w and (self.current_width - new_w > 20 or new_w - self.current_width > 3):
1209
+ self.set_width(new_w, set_TL=True, recreate_selection_boxes=False)
1210
1210
  return True
1211
1211
  return False
1212
1212
 
@@ -1310,7 +1310,8 @@ class RowIndex(tk.Canvas):
1310
1310
  mod = (self.MT.index_txt_height - 1) if self.MT.index_txt_height % 2 else self.MT.index_txt_height
1311
1311
  half_mod = mod / 2
1312
1312
  qtr_mod = mod / 4
1313
- mid_y = (self.MT.index_first_ln_ins - 1) if self.MT.index_first_ln_ins % 2 else self.MT.index_first_ln_ins
1313
+ small_mod = int(half_mod / 4) - 1
1314
+ mid_y = int(self.MT.min_row_height / 2)
1314
1315
  # up arrow
1315
1316
  if open_:
1316
1317
  points = (
@@ -1325,11 +1326,11 @@ class RowIndex(tk.Canvas):
1325
1326
  else:
1326
1327
  points = (
1327
1328
  x1 + half_mod + indent,
1328
- y1 + mid_y - half_mod + 1,
1329
- x1 + mod + indent - 1,
1329
+ y1 + mid_y - half_mod + small_mod,
1330
+ x1 + mod + indent - small_mod,
1330
1331
  y1 + mid_y,
1331
1332
  x1 + half_mod + indent,
1332
- y1 + mid_y + half_mod - 1,
1333
+ y1 + mid_y + half_mod - small_mod,
1333
1334
  )
1334
1335
  if self.hidd_tree_arrow:
1335
1336
  t, sh = self.hidd_tree_arrow.popitem()
@@ -1340,10 +1341,13 @@ class RowIndex(tk.Canvas):
1340
1341
  self.itemconfig(t, fill=fill, tag=tag, state="normal")
1341
1342
  self.lift(t)
1342
1343
  else:
1343
- t = self.create_polygon(
1344
+ t = self.create_line(
1344
1345
  points,
1345
1346
  fill=fill,
1346
1347
  tag=tag,
1348
+ width=2,
1349
+ capstyle=tk.ROUND,
1350
+ joinstyle=tk.BEVEL,
1347
1351
  )
1348
1352
  self.disp_tree_arrow[t] = True
1349
1353
 
@@ -1633,7 +1637,7 @@ class RowIndex(tk.Canvas):
1633
1637
  if align == "w":
1634
1638
  draw_x += self.MT.index_txt_height + 1
1635
1639
  indent = self.get_treeview_indent(iid)
1636
- draw_x += indent + 4
1640
+ draw_x += indent + 5
1637
1641
  if self.tree[iid].children:
1638
1642
  self.redraw_tree_arrow(
1639
1643
  0,
@@ -1738,11 +1742,11 @@ class RowIndex(tk.Canvas):
1738
1742
 
1739
1743
  def get_redraw_selections(self, startr: int, endr: int) -> dict[str, set[int]]:
1740
1744
  d = defaultdict(set)
1741
- for item, box in self.MT.get_selection_items(columns=False):
1745
+ for item, box in self.MT.get_selection_items():
1742
1746
  r1, c1, r2, c2 = box.coords
1743
1747
  for r in range(startr, endr):
1744
1748
  if r1 <= r and r2 > r:
1745
- d[box.type_].add(r)
1749
+ d[box.type_ if box.type_ != "columns" else "cells"].add(r)
1746
1750
  return d
1747
1751
 
1748
1752
  def open_cell(self, event: object = None, ignore_existing_editor=False):
@@ -130,7 +130,8 @@ class Sheet(tk.Frame):
130
130
  show_default_header_for_empty: bool = True,
131
131
  show_default_index_for_empty: bool = True,
132
132
  page_up_down_select_row: bool = True,
133
- expand_sheet_if_paste_too_big: bool = False,
133
+ paste_can_expand_x: bool = False,
134
+ paste_can_expand_y: bool = False,
134
135
  paste_insert_column_limit: int | None = None,
135
136
  paste_insert_row_limit: int | None = None,
136
137
  show_dropdown_borders: bool = False,
@@ -265,6 +266,7 @@ class Sheet(tk.Frame):
265
266
  header_height: str | int | None = None,
266
267
  row_height: str | int | None = None,
267
268
  row_index_width: int | None = None,
269
+ expand_sheet_if_paste_too_big: bool | None = None,
268
270
  ) -> None:
269
271
  tk.Frame.__init__(
270
272
  self,
@@ -283,6 +285,9 @@ class Sheet(tk.Frame):
283
285
  default_row_height = row_height
284
286
  if row_index_width is not None:
285
287
  default_row_index_width = row_index_width
288
+ if expand_sheet_if_paste_too_big is not None:
289
+ paste_can_expand_x = expand_sheet_if_paste_too_big
290
+ paste_can_expand_y = expand_sheet_if_paste_too_big
286
291
  if treeview:
287
292
  index_align = "w"
288
293
  auto_resize_row_index = True
@@ -1459,6 +1464,8 @@ class Sheet(tk.Frame):
1459
1464
  undo_stack: bool = True,
1460
1465
  selections: bool = True,
1461
1466
  sheet_options: bool = False,
1467
+ displayed_rows: bool = True,
1468
+ displayed_columns: bool = True,
1462
1469
  tree: bool = True,
1463
1470
  redraw: bool = True,
1464
1471
  ) -> Sheet:
@@ -1471,6 +1478,12 @@ class Sheet(tk.Frame):
1471
1478
  if index:
1472
1479
  self.RI.hide_text_editor_and_dropdown(redraw=False)
1473
1480
  self.MT._row_index = []
1481
+ if displayed_columns:
1482
+ self.MT.displayed_columns = []
1483
+ self.MT.all_columns_displayed = True
1484
+ if displayed_rows:
1485
+ self.MT.displayed_rows = []
1486
+ self.MT.all_rows_displayed = True
1474
1487
  if row_heights:
1475
1488
  self.MT.saved_row_heights = {}
1476
1489
  self.MT.set_row_positions([])
@@ -3579,6 +3592,20 @@ class Sheet(tk.Frame):
3579
3592
  z < self.MT.min_column_width or not isinstance(z, int) or isinstance(z, bool) for z in column_widths
3580
3593
  )
3581
3594
 
3595
+ def valid_row_height(self, height: int) -> int:
3596
+ if height < self.MT.min_row_height:
3597
+ return self.MT.min_row_height
3598
+ elif height > self.MT.max_row_height:
3599
+ return self.MT.max_row_height
3600
+ return height
3601
+
3602
+ def valid_column_width(self, width: int) -> int:
3603
+ if width < self.MT.min_column_width:
3604
+ return self.MT.min_column_width
3605
+ elif width > self.MT.max_column_width:
3606
+ return self.MT.max_column_width
3607
+ return width
3608
+
3582
3609
  # Identifying Bound Event Mouse Position
3583
3610
 
3584
3611
  def identify_region(self, event: object) -> Literal["table", "index", "header", "top left"]:
@@ -4178,10 +4205,13 @@ class Sheet(tk.Frame):
4178
4205
  self.MT.max_header_height = float(kwargs["max_header_height"])
4179
4206
  if "max_index_width" in kwargs:
4180
4207
  self.MT.max_index_width = float(kwargs["max_index_width"])
4208
+ if "expand_sheet_if_paste_too_big" in kwargs:
4209
+ self.ops.paste_can_expand_x = kwargs["expand_sheet_if_paste_too_big"]
4210
+ self.ops.paste_can_expand_y = kwargs["expand_sheet_if_paste_too_big"]
4181
4211
  if "font" in kwargs:
4182
4212
  self.MT.set_table_font(kwargs["font"])
4183
4213
  elif "table_font" in kwargs:
4184
- self.MT.set_table_font(kwargs["font"])
4214
+ self.MT.set_table_font(kwargs["table_font"])
4185
4215
  if "header_font" in kwargs:
4186
4216
  self.MT.set_header_font(kwargs["header_font"])
4187
4217
  if "index_font" in kwargs:
@@ -4504,6 +4534,7 @@ class Sheet(tk.Frame):
4504
4534
  safety: bool = True,
4505
4535
  ncols: int | None = None,
4506
4536
  ) -> Sheet:
4537
+ self.reset(cell_options=False, column_widths=False, header=False, redraw=False)
4507
4538
  if text_column is None:
4508
4539
  text_column = iid_column
4509
4540
  tally_of_ids = defaultdict(lambda: -1)
@@ -4556,6 +4587,8 @@ class Sheet(tk.Frame):
4556
4587
  fill=False,
4557
4588
  push_ops=push_ops,
4558
4589
  )
4590
+ self.MT.all_rows_displayed = False
4591
+ self.MT.displayed_rows = list(range(len(self.MT._row_index)))
4559
4592
  self.RI.tree_rns = {n.iid: i for i, n in enumerate(self.MT._row_index)}
4560
4593
  if open_ids:
4561
4594
  self.tree_set_open(open_ids=open_ids)
@@ -4600,16 +4633,23 @@ class Sheet(tk.Frame):
4600
4633
  deselect_all=False,
4601
4634
  )
4602
4635
  return self.set_refresh_timer(True)
4603
-
4636
+
4604
4637
  def _tree_open(self, items: set[str]) -> list[int]:
4605
4638
  """
4606
4639
  Only meant for internal use
4607
4640
  """
4608
4641
  to_open = []
4642
+ disp_set = set(self.MT.displayed_rows)
4643
+ quick_rns = self.RI.tree_rns
4644
+ quick_open_ids = self.RI.tree_open_ids
4609
4645
  for item in filter(items.__contains__, self.get_children()):
4610
4646
  if self.RI.tree[item].children:
4611
- self.RI.tree_open_ids.add(item)
4612
- to_open.extend(self.RI.tree_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True))
4647
+ quick_open_ids.add(item)
4648
+ if quick_rns[item] in disp_set:
4649
+ to_disp = [quick_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True)]
4650
+ for i in to_disp:
4651
+ disp_set.add(i)
4652
+ to_open.extend(to_disp)
4613
4653
  return to_open
4614
4654
 
4615
4655
  def tree_open(self, *items, redraw: bool = True) -> Sheet:
@@ -4619,36 +4659,37 @@ class Sheet(tk.Frame):
4619
4659
  if items := set(unpack(items)):
4620
4660
  to_open = self._tree_open(items)
4621
4661
  else:
4622
- to_open = []
4623
- for item in self.get_children():
4624
- if self.RI.tree[item].children:
4625
- self.RI.tree_open_ids.add(item)
4626
- to_open.extend(self.RI.tree_rns[did] for did in self.RI.get_iid_descendants(item, check_open=True))
4662
+ to_open = self._tree_open(set(self.get_children()))
4627
4663
  return self.show_rows(
4628
4664
  rows=to_open,
4629
4665
  redraw=redraw,
4630
4666
  deselect_all=False,
4631
4667
  )
4632
4668
 
4669
+ def _tree_close(self, items: Iterator[str]) -> list[int]:
4670
+ """
4671
+ Only meant for internal use
4672
+ """
4673
+ to_close = set()
4674
+ disp_set = set(self.MT.displayed_rows)
4675
+ quick_rns = self.RI.tree_rns
4676
+ quick_open_ids = self.RI.tree_open_ids
4677
+ for item in items:
4678
+ if self.RI.tree[item].children:
4679
+ quick_open_ids.discard(item)
4680
+ if quick_rns[item] in disp_set:
4681
+ for did in self.RI.get_iid_descendants(item, check_open=True):
4682
+ to_close.add(quick_rns[did])
4683
+ return to_close
4684
+
4633
4685
  def tree_close(self, *items, redraw: bool = True) -> Sheet:
4634
4686
  """
4635
4687
  If used without args all items are closed
4636
4688
  """
4637
- to_close = set()
4638
4689
  if items:
4639
- for item in unpack(items):
4640
- if self.RI.tree[item].children:
4641
- self.RI.tree_open_ids.discard(item)
4642
- if self.RI.tree_rns[item] in self.MT.displayed_rows:
4643
- for did in self.RI.get_iid_descendants(item, check_open=True):
4644
- to_close.add(self.RI.tree_rns[did])
4690
+ to_close = self._tree_close(unpack(items))
4645
4691
  else:
4646
- for item in self.get_children():
4647
- if self.RI.tree[item].children:
4648
- self.RI.tree_open_ids.discard(item)
4649
- if self.RI.tree_rns[item] in self.MT.displayed_rows:
4650
- for did in self.RI.get_iid_descendants(item, check_open=True):
4651
- to_close.add(self.RI.tree_rns[did])
4692
+ to_close = self._tree_close(self.get_children())
4652
4693
  return self.hide_rows(
4653
4694
  rows=to_close,
4654
4695
  redraw=redraw,
@@ -218,7 +218,8 @@ def new_sheet_options() -> DotDict:
218
218
  "default_column_width": 120,
219
219
  "default_row_index_width": 70,
220
220
  "page_up_down_select_row": True,
221
- "expand_sheet_if_paste_too_big": False,
221
+ "paste_can_expand_x": False,
222
+ "paste_can_expand_y": False,
222
223
  "paste_insert_column_limit": None,
223
224
  "paste_insert_row_limit": None,
224
225
  "arrow_key_down_right_scroll_page": False,
@@ -26,7 +26,7 @@ class TextEditorTkText(tk.Text):
26
26
  self,
27
27
  parent,
28
28
  spacing1=0,
29
- spacing2=0,
29
+ spacing2=1,
30
30
  spacing3=0,
31
31
  bd=0,
32
32
  highlightthickness=0,
@@ -46,8 +46,8 @@ theme_light_blue: dict[str, str] = DotDict({
46
46
  "table_selected_columns_border_fg": "#0B57D0",
47
47
  "table_selected_columns_bg": "#E6EFFD",
48
48
  "table_selected_columns_fg": "black",
49
- "tree_arrow_fg": "#C4C7C5",
50
- "selected_cells_tree_arrow_fg": "#D3E3FD",
49
+ "tree_arrow_fg": "black",
50
+ "selected_cells_tree_arrow_fg": "black",
51
51
  "selected_rows_tree_arrow_fg": "#FFFFFF",
52
52
  "vertical_scroll_background": "#FFFFFF",
53
53
  "horizontal_scroll_background": "#FFFFFF",
@@ -121,7 +121,7 @@ theme_light_green: dict[str, str] = DotDict({
121
121
  "table_selected_columns_border_fg": "#107C41",
122
122
  "table_selected_columns_bg": "#E3E3E3",
123
123
  "table_selected_columns_fg": "black",
124
- "tree_arrow_fg": "#ababab",
124
+ "tree_arrow_fg": "black",
125
125
  "selected_cells_tree_arrow_fg": "#107C41",
126
126
  "selected_rows_tree_arrow_fg": "#FFFFFF",
127
127
  "vertical_scroll_background": "#FFFFFF",
@@ -272,8 +272,8 @@ theme_black: dict[str, str] = DotDict({
272
272
  "table_selected_columns_bg": "#404040",
273
273
  "table_selected_columns_fg": "#F7F7F7",
274
274
  "tree_arrow_fg": "#8C8C8C",
275
- "selected_cells_tree_arrow_fg": "#8C8C8C",
276
- "selected_rows_tree_arrow_fg": "#8C8C8C",
275
+ "selected_cells_tree_arrow_fg": "#FBB86C",
276
+ "selected_rows_tree_arrow_fg": "#000000",
277
277
  "vertical_scroll_background": "#3b3a39",
278
278
  "horizontal_scroll_background": "#3b3a39",
279
279
  "vertical_scroll_troughcolor": "#000000",
@@ -156,7 +156,7 @@ class TopLeftRectangle(tk.Canvas):
156
156
  self.unbind("<Double-Button-1>")
157
157
  self.unbind(rc_binding)
158
158
 
159
- def set_dimensions(self, new_w=None, new_h=None) -> None:
159
+ def set_dimensions(self, new_w=None, new_h=None, recreate_selection_boxes: bool = True) -> None:
160
160
  try:
161
161
  if new_h is None:
162
162
  h = self.winfo_height()
@@ -182,7 +182,8 @@ class TopLeftRectangle(tk.Canvas):
182
182
  h - 7,
183
183
  )
184
184
  self.coords(self.select_all_box, 0, 0, w - 5, h - 5)
185
- self.MT.recreate_all_selection_boxes()
185
+ if recreate_selection_boxes:
186
+ self.MT.recreate_all_selection_boxes()
186
187
 
187
188
  def mouse_motion(self, event: object = None) -> None:
188
189
  self.MT.reset_mouse_motion_creations()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tksheet
3
- Version: 7.1.23
3
+ Version: 7.2.0
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes