MoleditPy-linux 2.4.0__tar.gz → 2.4.1__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 (64) hide show
  1. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/PKG-INFO +1 -1
  2. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/pyproject.toml +1 -1
  3. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
  4. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/constants.py +1 -1
  5. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window.py +4 -0
  6. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_export.py +115 -1
  7. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_main_init.py +13 -0
  8. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/LICENSE +0 -0
  9. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/README.md +0 -0
  10. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/setup.cfg +0 -0
  11. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
  12. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
  13. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
  14. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
  15. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
  16. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/__init__.py +0 -0
  17. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/__main__.py +0 -0
  18. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/main.py +0 -0
  19. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/__init__.py +0 -0
  20. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/about_dialog.py +0 -0
  21. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/align_plane_dialog.py +0 -0
  22. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/alignment_dialog.py +0 -0
  23. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/analysis_window.py +0 -0
  24. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/angle_dialog.py +0 -0
  25. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/assets/file_icon.ico +0 -0
  26. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/assets/icon.icns +0 -0
  27. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/assets/icon.ico +0 -0
  28. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/assets/icon.png +0 -0
  29. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/atom_item.py +0 -0
  30. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/bond_item.py +0 -0
  31. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/bond_length_dialog.py +0 -0
  32. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/calculation_worker.py +0 -0
  33. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/color_settings_dialog.py +0 -0
  34. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/constrained_optimization_dialog.py +0 -0
  35. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/custom_interactor_style.py +0 -0
  36. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/custom_qt_interactor.py +0 -0
  37. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/dialog3_d_picking_mixin.py +0 -0
  38. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/dihedral_dialog.py +0 -0
  39. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_app_state.py +0 -0
  40. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_compute.py +0 -0
  41. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_dialog_manager.py +0 -0
  42. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_edit_3d.py +0 -0
  43. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_edit_actions.py +0 -0
  44. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_molecular_parsers.py +0 -0
  45. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_project_io.py +0 -0
  46. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_string_importers.py +0 -0
  47. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_ui_manager.py +0 -0
  48. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_view_3d.py +0 -0
  49. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/main_window_view_loaders.py +0 -0
  50. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/mirror_dialog.py +0 -0
  51. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/molecular_data.py +0 -0
  52. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/molecule_scene.py +0 -0
  53. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/move_group_dialog.py +0 -0
  54. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/periodic_table_dialog.py +0 -0
  55. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/planarize_dialog.py +0 -0
  56. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/plugin_interface.py +0 -0
  57. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/plugin_manager.py +0 -0
  58. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/plugin_manager_window.py +0 -0
  59. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/settings_dialog.py +0 -0
  60. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/template_preview_item.py +0 -0
  61. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/template_preview_view.py +0 -0
  62. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/translation_dialog.py +0 -0
  63. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/user_template_dialog.py +0 -0
  64. {moleditpy_linux-2.4.0 → moleditpy_linux-2.4.1}/src/moleditpy_linux/modules/zoomable_view.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy-linux
3
- Version: 2.4.0
3
+ Version: 2.4.1
4
4
  Summary: A cross-platform, simple, and intuitive molecular structure editor built in Python. It allows 2D molecular drawing and 3D structure visualization. It supports exporting structure files for input to DFT calculation software.
5
5
  Author-email: HiroYokoyama <titech.yoko.hiro@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "MoleditPy-linux"
7
7
 
8
- version = "2.4.0"
8
+ version = "2.4.1"
9
9
 
10
10
  license = {file = "LICENSE"}
11
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy-linux
3
- Version: 2.4.0
3
+ Version: 2.4.1
4
4
  Summary: A cross-platform, simple, and intuitive molecular structure editor built in Python. It allows 2D molecular drawing and 3D structure visualization. It supports exporting structure files for input to DFT calculation software.
5
5
  Author-email: HiroYokoyama <titech.yoko.hiro@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -16,7 +16,7 @@ from PyQt6.QtGui import QFont, QColor
16
16
  from rdkit import Chem
17
17
 
18
18
  #Version
19
- VERSION = '2.4.0'
19
+ VERSION = '2.4.1'
20
20
 
21
21
  ATOM_RADIUS = 18
22
22
  BOND_OFFSET = 3.5
@@ -500,6 +500,10 @@ class MainWindow(QMainWindow):
500
500
  # --- MOVED TO main_window_export.py ---
501
501
  return self.main_window_export.export_2d_png()
502
502
 
503
+ def export_2d_svg(self):
504
+ # --- MOVED TO main_window_export.py ---
505
+ return self.main_window_export.export_2d_svg()
506
+
503
507
  def export_3d_png(self):
504
508
  # --- MOVED TO main_window_export.py ---
505
509
  return self.main_window_export.export_3d_png()
@@ -37,9 +37,11 @@ from PyQt6.QtGui import (
37
37
  QBrush, QColor, QPainter, QImage
38
38
  )
39
39
 
40
+ from PyQt6.QtSvg import QSvgGenerator
41
+
40
42
 
41
43
  from PyQt6.QtCore import (
42
- Qt, QRectF
44
+ Qt, QRectF, QSize
43
45
  )
44
46
 
45
47
  import pyvista as pv
@@ -753,6 +755,118 @@ class MainWindowExport(object):
753
755
 
754
756
 
755
757
 
758
+ def export_2d_svg(self):
759
+ """2D drawingをSVGとしてエクスポート"""
760
+ if not self.data.atoms:
761
+ self.statusBar().showMessage("Nothing to export.")
762
+ return
763
+
764
+ # default filename
765
+ default_name = "untitled-2d"
766
+ try:
767
+ if self.current_file_path:
768
+ base = os.path.basename(self.current_file_path)
769
+ name = os.path.splitext(base)[0]
770
+ default_name = f"{name}-2d"
771
+ except Exception:
772
+ default_name = "untitled-2d"
773
+
774
+ # prefer same directory
775
+ default_path = default_name
776
+ try:
777
+ if self.current_file_path:
778
+ default_path = os.path.join(os.path.dirname(self.current_file_path), default_name)
779
+ except Exception:
780
+ default_path = default_name
781
+
782
+ filePath, _ = QFileDialog.getSaveFileName(self, "Export 2D as SVG", default_path, "SVG Files (*.svg)")
783
+ if not filePath:
784
+ return
785
+
786
+ if not (filePath.lower().endswith(".svg")):
787
+ filePath += ".svg"
788
+
789
+ # Ask about transparency
790
+ reply = QMessageBox.question(self, 'Choose Background',
791
+ 'Do you want a transparent background?\n(Choose "No" to use the current background color)',
792
+ QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No | QMessageBox.StandardButton.Cancel,
793
+ QMessageBox.StandardButton.Yes)
794
+
795
+ if reply == QMessageBox.StandardButton.Cancel:
796
+ self.statusBar().showMessage("Export cancelled.", 2000)
797
+ return
798
+
799
+ is_transparent = (reply == QMessageBox.StandardButton.Yes)
800
+
801
+ try:
802
+ # 1. Hide non-molecular items if needed (optional, keeping consistent with PNG export)
803
+ items_to_restore = {}
804
+ original_background = self.scene.backgroundBrush()
805
+
806
+ all_items = list(self.scene.items())
807
+ for item in all_items:
808
+ is_mol_part = isinstance(item, (AtomItem, BondItem))
809
+ if not (is_mol_part and item.isVisible()):
810
+ # Keep measurement items visible if they are part of the scene?
811
+ # For now, let's stick to hiding everything that isn't atom/bond,
812
+ # similar to png export logic, or we can decide to export everything visible.
813
+ # The PNG export hides non-atom/bond items. Let's follow that for consistency.
814
+ items_to_restore[item] = item.isVisible()
815
+ item.hide()
816
+
817
+ # 2. Calculate bounds
818
+ molecule_bounds = QRectF()
819
+ for item in self.scene.items():
820
+ if isinstance(item, (AtomItem, BondItem)) and item.isVisible():
821
+ molecule_bounds = molecule_bounds.united(item.sceneBoundingRect())
822
+
823
+ if molecule_bounds.isEmpty() or not molecule_bounds.isValid():
824
+ self.statusBar().showMessage("Error: Could not determine molecule bounds for export.")
825
+ # Restore
826
+ for item, was_visible in items_to_restore.items():
827
+ item.setVisible(was_visible)
828
+ return
829
+
830
+ if is_transparent:
831
+ self.scene.setBackgroundBrush(QBrush(Qt.BrushStyle.NoBrush))
832
+
833
+ # Margin
834
+ rect_to_render = molecule_bounds.adjusted(-20, -20, 20, 20)
835
+
836
+ width = int(rect_to_render.width())
837
+ height = int(rect_to_render.height())
838
+
839
+ # 3. Setup QSvgGenerator
840
+ generator = QSvgGenerator()
841
+ generator.setFileName(filePath)
842
+ generator.setSize(QSize(width, height))
843
+ generator.setViewBox(rect_to_render)
844
+ generator.setTitle("MoleditPy Molecule")
845
+
846
+ # 4. Render
847
+ painter = QPainter()
848
+ painter.begin(generator)
849
+ try:
850
+ self.scene.render(painter, rect_to_render, rect_to_render)
851
+ finally:
852
+ painter.end()
853
+
854
+ self.statusBar().showMessage(f"2D view exported to {filePath}")
855
+
856
+ except Exception as e:
857
+ self.statusBar().showMessage(f"An unexpected error occurred during SVG export: {e}")
858
+
859
+ finally:
860
+ # Restore
861
+ for item, was_visible in items_to_restore.items():
862
+ item.setVisible(was_visible)
863
+ if 'original_background' in locals():
864
+ self.scene.setBackgroundBrush(original_background)
865
+ if self.view_2d:
866
+ self.view_2d.viewport().update()
867
+
868
+
869
+
756
870
  def export_3d_png(self):
757
871
  if not self.current_mol:
758
872
  self.statusBar().showMessage("No 3D molecule to export.", 2000)
@@ -920,6 +920,10 @@ class MainWindowMainInit(object):
920
920
  export_2d_png_action = QAction("PNG Image...", self)
921
921
  export_2d_png_action.triggered.connect(self.export_2d_png)
922
922
  export_2d_menu.addAction(export_2d_png_action)
923
+
924
+ export_2d_svg_action = QAction("SVG Image...", self)
925
+ export_2d_svg_action.triggered.connect(self.export_2d_svg)
926
+ export_2d_menu.addAction(export_2d_svg_action)
923
927
 
924
928
  # 3D エクスポート
925
929
  export_3d_menu = export_menu.addMenu("3D Formats")
@@ -1597,6 +1601,15 @@ class MainWindowMainInit(object):
1597
1601
  except Exception:
1598
1602
  pass
1599
1603
  # Update 2D scene styling to reflect default CPK colors
1604
+ try:
1605
+ # Reset 2D background specifically
1606
+ if hasattr(self, 'scene') and self.scene:
1607
+ bg_c = self.settings.get('background_color_2d', '#FFFFFF')
1608
+ self.scene.setBackgroundBrush(QBrush(QColor(bg_c)))
1609
+
1610
+ self.update_cpk_colors_from_settings()
1611
+ except Exception:
1612
+ pass
1600
1613
  try:
1601
1614
  if hasattr(self, 'scene') and self.scene:
1602
1615
  for it in list(self.scene.items()):
File without changes