batplot 1.7.22__py3-none-any.whl → 1.7.24__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.

Potentially problematic release.


This version of batplot might be problematic. Click here for more details.

batplot/interactive.py CHANGED
@@ -866,10 +866,11 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
866
866
  )
867
867
 
868
868
  # NEW: export current style to .bpcfg
869
- def export_style_config(filename, base_path=None):
869
+ def export_style_config(filename, base_path=None, overwrite_path=None):
870
870
  cts = getattr(_bp, 'cif_tick_series', None) if _bp is not None else None
871
871
  show_titles = bool(getattr(_bp, 'show_cif_titles', True)) if _bp is not None else True
872
- return _bp_export_style_config(
872
+ from .style import export_style_config as _export_style_config
873
+ return _export_style_config(
873
874
  filename,
874
875
  fig,
875
876
  ax,
@@ -883,6 +884,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
883
884
  label_text_objects,
884
885
  base_path,
885
886
  show_cif_titles=show_titles,
887
+ overwrite_path=overwrite_path,
886
888
  )
887
889
 
888
890
  # NEW: apply imported style config (restricted application)
@@ -1467,6 +1469,17 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1467
1469
  else:
1468
1470
  continue
1469
1471
  elif key == 'z': # toggle hkl labels on CIF ticks (non-blocking)
1472
+ # Check if CIF files exist before allowing this command
1473
+ has_cif = False
1474
+ try:
1475
+ has_cif = any(f.split(':')[0].lower().endswith('.cif') for f in args.files)
1476
+ if not has_cif and _bp is not None:
1477
+ has_cif = bool(getattr(_bp, 'cif_tick_series', None))
1478
+ except Exception:
1479
+ pass
1480
+ if not has_cif:
1481
+ print("Unknown option.")
1482
+ continue
1470
1483
  try:
1471
1484
  # Flip visibility flag in batplot module
1472
1485
  cur = bool(getattr(_bp, 'show_cif_hkl', False)) if _bp is not None else False
@@ -1546,6 +1559,17 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1546
1559
  print(f"Error in legend submenu: {e}")
1547
1560
  continue
1548
1561
  elif key == 'j': # toggle CIF title labels (filename labels)
1562
+ # Check if CIF files exist before allowing this command
1563
+ has_cif = False
1564
+ try:
1565
+ has_cif = any(f.split(':')[0].lower().endswith('.cif') for f in args.files)
1566
+ if not has_cif and _bp is not None:
1567
+ has_cif = bool(getattr(_bp, 'cif_tick_series', None))
1568
+ except Exception:
1569
+ pass
1570
+ if not has_cif:
1571
+ print("Unknown option.")
1572
+ continue
1549
1573
  try:
1550
1574
  # Preserve both x and y-axis limits to prevent movement
1551
1575
  prev_xlim = ax.get_xlim()
@@ -1609,11 +1633,47 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1609
1633
  print(f" {i}: {f} ({timestamp})")
1610
1634
  else:
1611
1635
  print(f" {i}: {f}")
1612
- prompt = "Enter new filename (no ext needed) or number to overwrite (q=cancel): "
1636
+ last_session_path = getattr(fig, '_last_session_save_path', None)
1637
+ if last_session_path:
1638
+ prompt = "Enter new filename (no ext needed), number to overwrite, or o to overwrite last (q=cancel): "
1639
+ else:
1640
+ prompt = "Enter new filename (no ext needed) or number to overwrite (q=cancel): "
1613
1641
  choice = input(prompt).strip()
1614
1642
  if not choice or choice.lower() == 'q':
1615
1643
  print("Canceled.")
1616
1644
  continue
1645
+ if choice.lower() == 'o':
1646
+ # Overwrite last saved session
1647
+ if not last_session_path:
1648
+ print("No previous save found.")
1649
+ continue
1650
+ if not os.path.exists(last_session_path):
1651
+ print(f"Previous save file not found: {last_session_path}")
1652
+ continue
1653
+ yn = input(f"Overwrite '{os.path.basename(last_session_path)}'? (y/n): ").strip().lower()
1654
+ if yn != 'y':
1655
+ continue
1656
+ _bp_dump_session(
1657
+ last_session_path,
1658
+ fig=fig,
1659
+ ax=ax,
1660
+ x_data_list=x_data_list,
1661
+ y_data_list=y_data_list,
1662
+ orig_y=orig_y,
1663
+ offsets_list=offsets_list,
1664
+ labels=labels,
1665
+ delta=delta,
1666
+ args=args,
1667
+ tick_state=tick_state,
1668
+ cif_tick_series=(getattr(_bp, 'cif_tick_series', None) if _bp is not None else None),
1669
+ cif_hkl_map=(getattr(_bp, 'cif_hkl_map', None) if _bp is not None else None),
1670
+ cif_hkl_label_map=(getattr(_bp, 'cif_hkl_label_map', None) if _bp is not None else None),
1671
+ show_cif_hkl=(bool(getattr(_bp,'show_cif_hkl', False)) if _bp is not None else False),
1672
+ show_cif_titles=(bool(getattr(_bp,'show_cif_titles', True)) if _bp is not None else True),
1673
+ skip_confirm=True,
1674
+ )
1675
+ print(f"Overwritten session to {last_session_path}")
1676
+ continue
1617
1677
  target_path = None
1618
1678
  # Overwrite by number
1619
1679
  if choice.isdigit() and files:
@@ -1626,10 +1686,32 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1626
1686
  continue
1627
1687
  target_path = os.path.join(folder, name)
1628
1688
  skip_confirm = True # Already confirmed above
1689
+ _bp_dump_session(
1690
+ target_path,
1691
+ fig=fig,
1692
+ ax=ax,
1693
+ x_data_list=x_data_list,
1694
+ y_data_list=y_data_list,
1695
+ orig_y=orig_y,
1696
+ offsets_list=offsets_list,
1697
+ labels=labels,
1698
+ delta=delta,
1699
+ args=args,
1700
+ tick_state=tick_state,
1701
+ cif_tick_series=(getattr(_bp, 'cif_tick_series', None) if _bp is not None else None),
1702
+ cif_hkl_map=(getattr(_bp, 'cif_hkl_map', None) if _bp is not None else None),
1703
+ cif_hkl_label_map=(getattr(_bp, 'cif_hkl_label_map', None) if _bp is not None else None),
1704
+ show_cif_hkl=(bool(getattr(_bp,'show_cif_hkl', False)) if _bp is not None else False),
1705
+ show_cif_titles=(bool(getattr(_bp,'show_cif_titles', True)) if _bp is not None else True),
1706
+ skip_confirm=skip_confirm,
1707
+ )
1708
+ print(f"Saved session to {target_path}")
1709
+ fig._last_session_save_path = target_path
1710
+ continue
1629
1711
  else:
1630
1712
  print("Invalid number.")
1631
1713
  continue
1632
- else:
1714
+ if choice.lower() != 'o':
1633
1715
  # New name, allow relative or absolute
1634
1716
  name = choice
1635
1717
  root, ext = os.path.splitext(name)
@@ -1643,27 +1725,28 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1643
1725
  print("Canceled.")
1644
1726
  continue
1645
1727
  skip_confirm = True # Already confirmed
1646
- # Delegate to session dumper
1647
- _bp_dump_session(
1648
- target_path,
1649
- fig=fig,
1650
- ax=ax,
1651
- x_data_list=x_data_list,
1652
- y_data_list=y_data_list,
1653
- orig_y=orig_y,
1654
- offsets_list=offsets_list,
1655
- labels=labels,
1656
- delta=delta,
1657
- args=args,
1658
- tick_state=tick_state,
1659
- cif_tick_series=(getattr(_bp, 'cif_tick_series', None) if _bp is not None else None),
1660
- cif_hkl_map=(getattr(_bp, 'cif_hkl_map', None) if _bp is not None else None),
1661
- cif_hkl_label_map=(getattr(_bp, 'cif_hkl_label_map', None) if _bp is not None else None),
1662
- show_cif_hkl=(bool(getattr(_bp,'show_cif_hkl', False)) if _bp is not None else False),
1663
- show_cif_titles=(bool(getattr(_bp,'show_cif_titles', True)) if _bp is not None else True),
1664
- skip_confirm=skip_confirm,
1665
- )
1666
- print(f"Saved session to {target_path}")
1728
+ # Delegate to session dumper
1729
+ _bp_dump_session(
1730
+ target_path,
1731
+ fig=fig,
1732
+ ax=ax,
1733
+ x_data_list=x_data_list,
1734
+ y_data_list=y_data_list,
1735
+ orig_y=orig_y,
1736
+ offsets_list=offsets_list,
1737
+ labels=labels,
1738
+ delta=delta,
1739
+ args=args,
1740
+ tick_state=tick_state,
1741
+ cif_tick_series=(getattr(_bp, 'cif_tick_series', None) if _bp is not None else None),
1742
+ cif_hkl_map=(getattr(_bp, 'cif_hkl_map', None) if _bp is not None else None),
1743
+ cif_hkl_label_map=(getattr(_bp, 'cif_hkl_label_map', None) if _bp is not None else None),
1744
+ show_cif_hkl=(bool(getattr(_bp,'show_cif_hkl', False)) if _bp is not None else False),
1745
+ show_cif_titles=(bool(getattr(_bp,'show_cif_titles', True)) if _bp is not None else True),
1746
+ skip_confirm=skip_confirm,
1747
+ )
1748
+ print(f"Saved session to {target_path}")
1749
+ fig._last_session_save_path = target_path
1667
1750
  except Exception as e:
1668
1751
  print(f"Error saving session: {e}")
1669
1752
  continue
@@ -3493,11 +3576,32 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3493
3576
  print(f" {_i}: {fname} ({timestamp})")
3494
3577
  else:
3495
3578
  print(f" {_i}: {fname}")
3496
- sub = input(colorize_prompt("Style submenu: (e=export, q=return, r=refresh): ")).strip().lower()
3579
+ last_style_path = getattr(fig, '_last_style_export_path', None)
3580
+ if last_style_path:
3581
+ sub = input(colorize_prompt("Style submenu: (e=export, o=overwrite last, q=return, r=refresh): ")).strip().lower()
3582
+ else:
3583
+ sub = input(colorize_prompt("Style submenu: (e=export, q=return, r=refresh): ")).strip().lower()
3497
3584
  if sub == 'q':
3498
3585
  break
3499
3586
  if sub == 'r' or sub == '':
3500
3587
  continue
3588
+ if sub == 'o':
3589
+ # Overwrite last exported style file
3590
+ if not last_style_path:
3591
+ print("No previous export found.")
3592
+ continue
3593
+ if not os.path.exists(last_style_path):
3594
+ print(f"Previous export file not found: {last_style_path}")
3595
+ continue
3596
+ yn = input(f"Overwrite '{os.path.basename(last_style_path)}'? (y/n): ").strip().lower()
3597
+ if yn != 'y':
3598
+ continue
3599
+ # Call export_style_config with overwrite_path to skip dialog
3600
+ exported_path = export_style_config(None, base_path=None, overwrite_path=last_style_path)
3601
+ if exported_path:
3602
+ fig._last_style_export_path = exported_path
3603
+ style_menu_active = False
3604
+ break
3501
3605
  if sub == 'e':
3502
3606
  save_base = choose_save_path(source_file_paths, purpose="style export")
3503
3607
  if not save_base:
@@ -3505,7 +3609,9 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3505
3609
  continue
3506
3610
  print(f"\nChosen path: {save_base}")
3507
3611
  # Call export_style_config which handles the entire export dialog
3508
- export_style_config(None, base_path=save_base) # filename parameter ignored
3612
+ exported_path = export_style_config(None, base_path=save_base) # filename parameter ignored
3613
+ if exported_path:
3614
+ fig._last_style_export_path = exported_path
3509
3615
  style_menu_active = False # Exit style submenu and return to main menu
3510
3616
  break
3511
3617
  else:
@@ -3543,14 +3649,33 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3543
3649
  else:
3544
3650
  print(f" {i}: {fname}")
3545
3651
 
3546
- filename = input("Enter filename (default SVG if no extension) or number to overwrite (q=cancel): ").strip()
3652
+ last_figure_path = getattr(fig, '_last_figure_export_path', None)
3653
+ if last_figure_path:
3654
+ filename = input("Enter filename (default SVG if no extension), number to overwrite, or o to overwrite last (q=cancel): ").strip()
3655
+ else:
3656
+ filename = input("Enter filename (default SVG if no extension) or number to overwrite (q=cancel): ").strip()
3547
3657
  if not filename or filename.lower() == 'q':
3548
3658
  print("Canceled.")
3549
3659
  continue
3550
3660
 
3661
+ already_confirmed = False # Initialize for new filename case
3662
+ # Check for 'o' option
3663
+ if filename.lower() == 'o':
3664
+ if not last_figure_path:
3665
+ print("No previous export found.")
3666
+ continue
3667
+ if not os.path.exists(last_figure_path):
3668
+ print(f"Previous export file not found: {last_figure_path}")
3669
+ continue
3670
+ yn = input(f"Overwrite '{os.path.basename(last_figure_path)}'? (y/n): ").strip().lower()
3671
+ if yn != 'y':
3672
+ print("Canceled.")
3673
+ continue
3674
+ export_target = last_figure_path
3675
+ already_confirmed = True
3551
3676
  # Check if user selected a number
3552
- already_confirmed = False
3553
- if filename.isdigit() and files:
3677
+ elif filename.isdigit() and files:
3678
+ already_confirmed = False
3554
3679
  idx = int(filename)
3555
3680
  if 1 <= idx <= len(files):
3556
3681
  name = files[idx-1]
@@ -3617,6 +3742,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3617
3742
  else:
3618
3743
  fig.savefig(export_target, dpi=300)
3619
3744
  print(f"Figure saved to {export_target}")
3745
+ fig._last_figure_export_path = export_target
3620
3746
  for i, txt in enumerate(label_text_objects):
3621
3747
  txt.set_text(f"{i+1}: {labels[i]}")
3622
3748
  fig.canvas.draw()