MoleditPy-linux 4.8.2__tar.gz → 4.9.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.
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/PKG-INFO +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/README.md +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/pyproject.toml +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/MoleditPy_linux.egg-info/PKG-INFO +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/MoleditPy_linux.egg-info/SOURCES.txt +1 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/core/mol_geometry.py +54 -3
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/core/molecular_data.py +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/main.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/plugins/plugin_interface.py +12 -10
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/plugins/plugin_manager.py +30 -15
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/analysis_window.py +8 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/app_state.py +13 -7
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/atom_item.py +7 -7
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/base_picking_dialog.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/bond_item.py +5 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/calculation_worker.py +34 -26
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/compute_logic.py +23 -6
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +7 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/custom_interactor_style.py +4 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/custom_qt_interactor.py +5 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +8 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/edit_actions_logic.py +42 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/export_logic.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/io_logic.py +27 -8
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/main_window_init.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/molecular_scene_handler.py +6 -6
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/molecule_scene.py +6 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/move_group_dialog.py +3 -3
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/move_selected_atoms_dialog.py +3 -3
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/planarize_dialog.py +1 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/plugin_menu_manager.py +3 -1
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/settings_dialog.py +4 -0
- moleditpy_linux-4.9.0/src/moleditpy_linux/ui/settings_tabs/settings_2d_cleanup_tab.py +146 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +6 -5
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/string_importers.py +7 -7
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/template_preview_item.py +2 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/translation_dialog.py +14 -2
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/view_3d_logic.py +20 -20
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/default_settings.py +11 -6
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/LICENSE +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/setup.cfg +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/__main__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/assets/file_icon.ico +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/assets/icon.icns +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/assets/icon.ico +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/assets/icon.png +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/core/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/plugins/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/plugins/plugin_manager_window.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/about_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/atom_picking.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/chain_mixin.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/dialog_logic.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/main_window.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/preview_molecule.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/ui_manager.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/user_template_dialog.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/zoomable_view.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/__init__.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/constants.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/hit_radius.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/suppress_log.py +0 -0
- {moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/utils/system_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.9.0
|
|
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
|
|
@@ -709,7 +709,7 @@ Dynamic: license-file
|
|
|
709
709
|
[](https://pypi.org/project/MoleditPy/)
|
|
710
710
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
711
711
|
[](https://github.com/HiroYokoyama/python_molecular_editor/actions)
|
|
712
|
-
[](https://codecov.io/gh/HiroYokoyama/python_molecular_editor)
|
|
713
713
|
[](https://github.com/HiroYokoyama/python_molecular_editor/blob/main/tests/MANUAL_CHECKLIST.md)
|
|
714
714
|
[](https://github.com/HiroYokoyama/python_molecular_editor/blob/main/tests/pylint-score.txt)
|
|
715
715
|
[](https://pepy.tech/projects/moleditpy)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://pypi.org/project/MoleditPy/)
|
|
7
7
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
8
8
|
[](https://github.com/HiroYokoyama/python_molecular_editor/actions)
|
|
9
|
-
[](https://codecov.io/gh/HiroYokoyama/python_molecular_editor)
|
|
10
10
|
[](https://github.com/HiroYokoyama/python_molecular_editor/blob/main/tests/MANUAL_CHECKLIST.md)
|
|
11
11
|
[](https://github.com/HiroYokoyama/python_molecular_editor/blob/main/tests/pylint-score.txt)
|
|
12
12
|
[](https://pepy.tech/projects/moleditpy)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.9.0
|
|
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
|
|
@@ -709,7 +709,7 @@ Dynamic: license-file
|
|
|
709
709
|
[](https://pypi.org/project/MoleditPy/)
|
|
710
710
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
711
711
|
[](https://github.com/HiroYokoyama/python_molecular_editor/actions)
|
|
712
|
-
[](https://codecov.io/gh/HiroYokoyama/python_molecular_editor)
|
|
713
713
|
[](https://github.com/HiroYokoyama/python_molecular_editor/blob/main/tests/MANUAL_CHECKLIST.md)
|
|
714
714
|
[](https://github.com/HiroYokoyama/python_molecular_editor/blob/main/tests/pylint-score.txt)
|
|
715
715
|
[](https://pepy.tech/projects/moleditpy)
|
|
@@ -69,6 +69,7 @@ src/moleditpy_linux/ui/user_template_dialog.py
|
|
|
69
69
|
src/moleditpy_linux/ui/view_3d_logic.py
|
|
70
70
|
src/moleditpy_linux/ui/zoomable_view.py
|
|
71
71
|
src/moleditpy_linux/ui/settings_tabs/__init__.py
|
|
72
|
+
src/moleditpy_linux/ui/settings_tabs/settings_2d_cleanup_tab.py
|
|
72
73
|
src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py
|
|
73
74
|
src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py
|
|
74
75
|
src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py
|
|
@@ -591,12 +591,63 @@ def _identify_problems_rdkit(
|
|
|
591
591
|
return None
|
|
592
592
|
|
|
593
593
|
|
|
594
|
-
|
|
594
|
+
_TARGET_BOND_LENGTH = 1.5 # matches RDKit's default (non-CoordGen) bond length
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
def _normalize_bond_length(mol: Chem.Mol, target_length: float) -> None:
|
|
598
|
+
"""Rescale a molecule's 2D conformer so its average bond length matches target_length."""
|
|
599
|
+
if mol.GetNumBonds() == 0:
|
|
600
|
+
return
|
|
601
|
+
conf = mol.GetConformer()
|
|
602
|
+
total_len = 0.0
|
|
603
|
+
for bond in mol.GetBonds():
|
|
604
|
+
p1 = conf.GetAtomPosition(bond.GetBeginAtomIdx())
|
|
605
|
+
p2 = conf.GetAtomPosition(bond.GetEndAtomIdx())
|
|
606
|
+
total_len += ((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) ** 0.5
|
|
607
|
+
avg_len = total_len / mol.GetNumBonds()
|
|
608
|
+
if avg_len <= 1e-6:
|
|
609
|
+
return
|
|
610
|
+
factor = target_length / avg_len
|
|
611
|
+
for i in range(mol.GetNumAtoms()):
|
|
612
|
+
pos = conf.GetAtomPosition(i)
|
|
613
|
+
conf.SetAtomPosition(i, (pos.x * factor, pos.y * factor, pos.z))
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
def optimize_2d_coords(
|
|
617
|
+
mol: Chem.Mol,
|
|
618
|
+
prefer_coordgen: bool = False,
|
|
619
|
+
canonical_orientation: bool = True,
|
|
620
|
+
use_ring_templates: bool = False,
|
|
621
|
+
straighten_bonds: bool = False,
|
|
622
|
+
avoid_clashes: bool = False,
|
|
623
|
+
) -> Dict[int, Tuple[float, float]]:
|
|
595
624
|
"""Generate 2D coordinates using RDKit and return a map of (x, y) tuples."""
|
|
596
|
-
from rdkit.Chem import
|
|
625
|
+
from rdkit.Chem import rdDepictor
|
|
597
626
|
|
|
598
|
-
|
|
627
|
+
sample_kwargs = (
|
|
628
|
+
{"nFlipsPerSample": 3, "nSample": 200, "sampleSeed": 0xF00D}
|
|
629
|
+
if avoid_clashes
|
|
630
|
+
else {}
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
rdDepictor.SetPreferCoordGen(prefer_coordgen)
|
|
634
|
+
try:
|
|
635
|
+
rdDepictor.Compute2DCoords(
|
|
636
|
+
mol,
|
|
637
|
+
canonOrient=canonical_orientation,
|
|
638
|
+
useRingTemplates=use_ring_templates,
|
|
639
|
+
**sample_kwargs, # type: ignore[arg-type] # RDKit's generated overload differs by platform.
|
|
640
|
+
)
|
|
641
|
+
if straighten_bonds:
|
|
642
|
+
rdDepictor.StraightenDepiction(mol)
|
|
643
|
+
finally:
|
|
644
|
+
rdDepictor.SetPreferCoordGen(False)
|
|
645
|
+
# CoordGen and the default generator use different internal bond-length
|
|
646
|
+
# conventions (~1.0 vs ~1.5), so normalize here to keep the on-screen
|
|
647
|
+
# scale consistent regardless of which algorithm produced the layout.
|
|
648
|
+
_normalize_bond_length(mol, _TARGET_BOND_LENGTH)
|
|
599
649
|
conf = mol.GetConformer()
|
|
650
|
+
|
|
600
651
|
new_positions = {}
|
|
601
652
|
for rdkit_atom in mol.GetAtoms():
|
|
602
653
|
if rdkit_atom.HasProp("_original_atom_id"):
|
|
@@ -20,7 +20,7 @@ import sys
|
|
|
20
20
|
import argparse
|
|
21
21
|
import time
|
|
22
22
|
import traceback
|
|
23
|
-
from typing import Any, Dict, Optional
|
|
23
|
+
from typing import Any, Dict, Optional, Set
|
|
24
24
|
|
|
25
25
|
from .utils.constants import VERSION
|
|
26
26
|
|
|
@@ -81,7 +81,7 @@ class _ErrorDialogHandler(logging.Handler):
|
|
|
81
81
|
# signature -> monotonic timestamp of its last shown dialog.
|
|
82
82
|
self._last_shown: Dict[str, float] = {}
|
|
83
83
|
# Held so a non-blocking box is not garbage-collected before it closes.
|
|
84
|
-
self._open_boxes:
|
|
84
|
+
self._open_boxes: Set[QMessageBox] = set()
|
|
85
85
|
self._log_path = log_path
|
|
86
86
|
|
|
87
87
|
def emit(self, record: logging.LogRecord) -> None:
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/plugins/plugin_interface.py
RENAMED
|
@@ -27,7 +27,7 @@ class PluginContext:
|
|
|
27
27
|
def add_menu_action(
|
|
28
28
|
self,
|
|
29
29
|
path: str,
|
|
30
|
-
callback: Callable,
|
|
30
|
+
callback: Callable[..., Any],
|
|
31
31
|
text: Optional[str] = None,
|
|
32
32
|
icon: Optional[str] = None,
|
|
33
33
|
shortcut: Optional[str] = None,
|
|
@@ -57,8 +57,8 @@ class PluginContext:
|
|
|
57
57
|
def register_menu_action(
|
|
58
58
|
self,
|
|
59
59
|
path: str,
|
|
60
|
-
text_or_callback: Union[str, Callable],
|
|
61
|
-
callback: Optional[Callable] = None,
|
|
60
|
+
text_or_callback: Union[str, Callable[..., Any]],
|
|
61
|
+
callback: Optional[Callable[..., Any]] = None,
|
|
62
62
|
icon: Optional[str] = None,
|
|
63
63
|
shortcut: Optional[str] = None,
|
|
64
64
|
) -> None:
|
|
@@ -76,7 +76,7 @@ class PluginContext:
|
|
|
76
76
|
def add_plugin_menu(
|
|
77
77
|
self,
|
|
78
78
|
path: str,
|
|
79
|
-
callback: Callable,
|
|
79
|
+
callback: Callable[..., Any],
|
|
80
80
|
text: Optional[str] = None,
|
|
81
81
|
icon: Optional[str] = None,
|
|
82
82
|
shortcut: Optional[str] = None,
|
|
@@ -103,7 +103,7 @@ class PluginContext:
|
|
|
103
103
|
|
|
104
104
|
def add_toolbar_action(
|
|
105
105
|
self,
|
|
106
|
-
callback: Callable,
|
|
106
|
+
callback: Callable[..., Any],
|
|
107
107
|
text: str,
|
|
108
108
|
icon: Optional[str] = None,
|
|
109
109
|
tooltip: Optional[str] = None,
|
|
@@ -262,7 +262,7 @@ class PluginContext:
|
|
|
262
262
|
if mw and hasattr(mw, "view_3d_manager") and mw.view_3d_manager.plotter:
|
|
263
263
|
mw.view_3d_manager.plotter.reset_camera()
|
|
264
264
|
|
|
265
|
-
def add_export_action(self, label: str, callback: Callable) -> None:
|
|
265
|
+
def add_export_action(self, label: str, callback: Callable[..., Any]) -> None:
|
|
266
266
|
"""
|
|
267
267
|
Register a custom export action.
|
|
268
268
|
|
|
@@ -303,7 +303,7 @@ class PluginContext:
|
|
|
303
303
|
self._plugin_name, extension, callback, priority
|
|
304
304
|
)
|
|
305
305
|
|
|
306
|
-
def add_analysis_tool(self, label: str, callback: Callable) -> None:
|
|
306
|
+
def add_analysis_tool(self, label: str, callback: Callable[..., Any]) -> None:
|
|
307
307
|
"""
|
|
308
308
|
Register a tool in the Analysis menu.
|
|
309
309
|
|
|
@@ -313,7 +313,7 @@ class PluginContext:
|
|
|
313
313
|
"""
|
|
314
314
|
self._manager.register_analysis_tool(self._plugin_name, label, callback)
|
|
315
315
|
|
|
316
|
-
def register_save_handler(self, callback: Callable[[],
|
|
316
|
+
def register_save_handler(self, callback: Callable[[], Dict[str, Any]]) -> None:
|
|
317
317
|
"""
|
|
318
318
|
Register a callback to save state into the project file.
|
|
319
319
|
|
|
@@ -322,7 +322,7 @@ class PluginContext:
|
|
|
322
322
|
"""
|
|
323
323
|
self._manager.register_save_handler(self._plugin_name, callback)
|
|
324
324
|
|
|
325
|
-
def register_load_handler(self, callback: Callable[[
|
|
325
|
+
def register_load_handler(self, callback: Callable[[Dict[str, Any]], None]) -> None:
|
|
326
326
|
"""
|
|
327
327
|
Register a callback to restore state from the project file.
|
|
328
328
|
|
|
@@ -331,7 +331,9 @@ class PluginContext:
|
|
|
331
331
|
"""
|
|
332
332
|
self._manager.register_load_handler(self._plugin_name, callback)
|
|
333
333
|
|
|
334
|
-
def register_3d_context_menu(
|
|
334
|
+
def register_3d_context_menu(
|
|
335
|
+
self, callback: Callable[..., Any], label: str
|
|
336
|
+
) -> None:
|
|
335
337
|
"""Deprecated: This method does nothing. Kept for backward compatibility."""
|
|
336
338
|
import warnings
|
|
337
339
|
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/plugins/plugin_manager.py
RENAMED
|
@@ -92,8 +92,8 @@ class PluginManager:
|
|
|
92
92
|
self.optimization_methods: Dict[str, Dict[str, Any]] = {}
|
|
93
93
|
self.file_openers: Dict[str, List[Dict[str, Any]]] = {}
|
|
94
94
|
self.analysis_tools: List[Dict[str, Any]] = []
|
|
95
|
-
self.save_handlers: Dict[str, Callable] = {}
|
|
96
|
-
self.load_handlers: Dict[str, Callable] = {}
|
|
95
|
+
self.save_handlers: Dict[str, Callable[..., Any]] = {}
|
|
96
|
+
self.load_handlers: Dict[str, Callable[..., Any]] = {}
|
|
97
97
|
self.custom_3d_styles: Dict[str, Dict[str, Any]] = {}
|
|
98
98
|
self.document_reset_handlers: List[Dict[str, Any]] = []
|
|
99
99
|
self.atom_drag_handlers: List[Dict[str, Any]] = []
|
|
@@ -447,7 +447,7 @@ class PluginManager:
|
|
|
447
447
|
self,
|
|
448
448
|
plugin_name: str,
|
|
449
449
|
path: str,
|
|
450
|
-
callback: Callable,
|
|
450
|
+
callback: Callable[..., Any],
|
|
451
451
|
text: str,
|
|
452
452
|
icon: str,
|
|
453
453
|
shortcut: str,
|
|
@@ -471,7 +471,12 @@ class PluginManager:
|
|
|
471
471
|
)
|
|
472
472
|
|
|
473
473
|
def register_toolbar_action(
|
|
474
|
-
self,
|
|
474
|
+
self,
|
|
475
|
+
plugin_name: str,
|
|
476
|
+
callback: Callable[..., Any],
|
|
477
|
+
text: str,
|
|
478
|
+
icon: str,
|
|
479
|
+
tooltip: str,
|
|
475
480
|
) -> None:
|
|
476
481
|
"""Register a plugin toolbar button with its callback and display metadata."""
|
|
477
482
|
self.toolbar_actions.append(
|
|
@@ -485,7 +490,7 @@ class PluginManager:
|
|
|
485
490
|
)
|
|
486
491
|
|
|
487
492
|
def register_drop_handler(
|
|
488
|
-
self, plugin_name: str, callback: Callable, priority: int
|
|
493
|
+
self, plugin_name: str, callback: Callable[..., Any], priority: int
|
|
489
494
|
) -> None:
|
|
490
495
|
"""Register a drag-and-drop handler with a given priority."""
|
|
491
496
|
self.drop_handlers.append(
|
|
@@ -495,7 +500,7 @@ class PluginManager:
|
|
|
495
500
|
self.drop_handlers.sort(key=lambda x: x["priority"], reverse=True)
|
|
496
501
|
|
|
497
502
|
def register_export_action(
|
|
498
|
-
self, plugin_name: str, label: str, callback: Callable
|
|
503
|
+
self, plugin_name: str, label: str, callback: Callable[..., Any]
|
|
499
504
|
) -> None:
|
|
500
505
|
"""Register a plugin export action with its label and callback."""
|
|
501
506
|
self.export_actions.append(
|
|
@@ -503,7 +508,7 @@ class PluginManager:
|
|
|
503
508
|
)
|
|
504
509
|
|
|
505
510
|
def register_optimization_method(
|
|
506
|
-
self, plugin_name: str, method_name: str, callback: Callable
|
|
511
|
+
self, plugin_name: str, method_name: str, callback: Callable[..., Any]
|
|
507
512
|
) -> None:
|
|
508
513
|
"""Register a named 3D optimization method provided by a plugin."""
|
|
509
514
|
method_key = method_name.upper()
|
|
@@ -520,7 +525,11 @@ class PluginManager:
|
|
|
520
525
|
)
|
|
521
526
|
|
|
522
527
|
def register_file_opener(
|
|
523
|
-
self,
|
|
528
|
+
self,
|
|
529
|
+
plugin_name: str,
|
|
530
|
+
extension: str,
|
|
531
|
+
callback: Callable[..., Any],
|
|
532
|
+
priority: int = 0,
|
|
524
533
|
) -> None:
|
|
525
534
|
"""Register a file-type handler for the given extension."""
|
|
526
535
|
# Normalize extension to lowercase
|
|
@@ -540,7 +549,7 @@ class PluginManager:
|
|
|
540
549
|
|
|
541
550
|
# Analysis Tools registration
|
|
542
551
|
def register_analysis_tool(
|
|
543
|
-
self, plugin_name: str, label: str, callback: Callable
|
|
552
|
+
self, plugin_name: str, label: str, callback: Callable[..., Any]
|
|
544
553
|
) -> None:
|
|
545
554
|
"""Register a plugin analysis tool with its label and callback."""
|
|
546
555
|
self.analysis_tools.append(
|
|
@@ -548,16 +557,20 @@ class PluginManager:
|
|
|
548
557
|
)
|
|
549
558
|
|
|
550
559
|
# State Persistence registration
|
|
551
|
-
def register_save_handler(
|
|
560
|
+
def register_save_handler(
|
|
561
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
562
|
+
) -> None:
|
|
552
563
|
"""Register a plugin session-save callback."""
|
|
553
564
|
self.save_handlers[plugin_name] = callback
|
|
554
565
|
|
|
555
|
-
def register_load_handler(
|
|
566
|
+
def register_load_handler(
|
|
567
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
568
|
+
) -> None:
|
|
556
569
|
"""Register a plugin session-load callback."""
|
|
557
570
|
self.load_handlers[plugin_name] = callback
|
|
558
571
|
|
|
559
572
|
def register_3d_style(
|
|
560
|
-
self, plugin_name: str, style_name: str, callback: Callable
|
|
573
|
+
self, plugin_name: str, style_name: str, callback: Callable[..., Any]
|
|
561
574
|
) -> None:
|
|
562
575
|
"""Register a named custom 3D rendering style."""
|
|
563
576
|
self.custom_3d_styles[style_name] = {
|
|
@@ -566,14 +579,16 @@ class PluginManager:
|
|
|
566
579
|
}
|
|
567
580
|
|
|
568
581
|
def register_document_reset_handler(
|
|
569
|
-
self, plugin_name: str, callback: Callable
|
|
582
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
570
583
|
) -> None:
|
|
571
584
|
"""Register callback to be invoked when a new document is created."""
|
|
572
585
|
self.document_reset_handlers.append(
|
|
573
586
|
{"plugin": plugin_name, "callback": callback}
|
|
574
587
|
)
|
|
575
588
|
|
|
576
|
-
def register_atom_drag_handler(
|
|
589
|
+
def register_atom_drag_handler(
|
|
590
|
+
self, plugin_name: str, callback: Callable[..., Any]
|
|
591
|
+
) -> None:
|
|
577
592
|
"""Register a handler called during 3D atom/group dragging."""
|
|
578
593
|
self.atom_drag_handlers.append({"plugin": plugin_name, "callback": callback})
|
|
579
594
|
|
|
@@ -676,7 +691,7 @@ class PluginManager:
|
|
|
676
691
|
self,
|
|
677
692
|
event_type: str,
|
|
678
693
|
atom_indices: List[int],
|
|
679
|
-
positions: Dict[int,
|
|
694
|
+
positions: Dict[int, Tuple[float, ...]],
|
|
680
695
|
) -> None:
|
|
681
696
|
"""Call all registered atom drag handlers."""
|
|
682
697
|
for handler in self.atom_drag_handlers:
|
|
@@ -75,7 +75,7 @@ class AnalysisWindow(QDialog):
|
|
|
75
75
|
total_atoms = len(xyz_atoms)
|
|
76
76
|
num_heavy_atoms = 0
|
|
77
77
|
|
|
78
|
-
for symbol,
|
|
78
|
+
for symbol, _x, _y, _z in xyz_atoms:
|
|
79
79
|
atom_counts[symbol] = atom_counts.get(symbol, 0) + 1
|
|
80
80
|
if symbol != "H": # Non-hydrogen
|
|
81
81
|
num_heavy_atoms += 1
|
|
@@ -154,12 +154,15 @@ class AnalysisWindow(QDialog):
|
|
|
154
154
|
|
|
155
155
|
# Calculate various properties
|
|
156
156
|
mol_formula = rdMolDescriptors.CalcMolFormula(self.mol)
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
# Descriptors.MolWt is generated at import time from rdkit's
|
|
158
|
+
# descriptor table, so no stub can declare it; the rest have
|
|
159
|
+
# direct rdMolDescriptors equivalents used elsewhere here.
|
|
160
|
+
mol_wt = Descriptors.MolWt(self.mol) # type: ignore[attr-defined]
|
|
161
|
+
exact_mw = rdMolDescriptors.CalcExactMolWt(self.mol)
|
|
159
162
|
num_heavy_atoms = self.mol.GetNumHeavyAtoms()
|
|
160
163
|
num_rings = rdMolDescriptors.CalcNumRings(self.mol)
|
|
161
|
-
log_p =
|
|
162
|
-
tpsa =
|
|
164
|
+
log_p = rdMolDescriptors.CalcCrippenDescriptors(self.mol)[0]
|
|
165
|
+
tpsa = rdMolDescriptors.CalcTPSA(self.mol)
|
|
163
166
|
num_h_donors = rdMolDescriptors.CalcNumHBD(self.mol)
|
|
164
167
|
num_h_acceptors = rdMolDescriptors.CalcNumHBA(self.mol)
|
|
165
168
|
|
|
@@ -19,7 +19,7 @@ import copy
|
|
|
19
19
|
import logging
|
|
20
20
|
import os
|
|
21
21
|
from ..utils.suppress_log import suppress_log
|
|
22
|
-
from typing import Any, Dict, Optional, Tuple
|
|
22
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
import numpy as np
|
|
@@ -43,7 +43,7 @@ if TYPE_CHECKING:
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
# --- Class Definition ---
|
|
46
|
-
def _serialize_constraints(constraints:
|
|
46
|
+
def _serialize_constraints(constraints: List[Any]) -> List[List[Any]]:
|
|
47
47
|
"""Convert internal constraint tuples to JSON-serializable lists."""
|
|
48
48
|
result = []
|
|
49
49
|
for const in constraints:
|
|
@@ -54,7 +54,7 @@ def _serialize_constraints(constraints: list) -> list:
|
|
|
54
54
|
return result
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def _deserialize_constraints(raw:
|
|
57
|
+
def _deserialize_constraints(raw: List[Any]) -> List[Tuple[Any, ...]]:
|
|
58
58
|
"""Convert JSON-loaded constraint lists back to internal tuples."""
|
|
59
59
|
result = []
|
|
60
60
|
for const in raw:
|
|
@@ -228,7 +228,7 @@ class StateManager:
|
|
|
228
228
|
if self.host.view_3d_manager.plotter and not getattr(
|
|
229
229
|
self.host, "is_restoring_state", False
|
|
230
230
|
):
|
|
231
|
-
self.host.view_3d_manager.plotter.reset_camera()
|
|
231
|
+
self.host.view_3d_manager.plotter.reset_camera() # type: ignore[call-arg]
|
|
232
232
|
|
|
233
233
|
self.host.ui_manager.enable_3d_features(True)
|
|
234
234
|
self.host.view_3d_manager.setup_3d_hover()
|
|
@@ -481,7 +481,9 @@ class StateManager:
|
|
|
481
481
|
json_data["molecular_info"] = {
|
|
482
482
|
"num_atoms": self.host.view_3d_manager.current_mol.GetNumAtoms(),
|
|
483
483
|
"num_bonds": self.host.view_3d_manager.current_mol.GetNumBonds(),
|
|
484
|
-
|
|
484
|
+
# Generated at import time from rdkit's descriptor
|
|
485
|
+
# table, so no stub can declare it.
|
|
486
|
+
"molecular_weight": Descriptors.MolWt( # type: ignore[attr-defined]
|
|
485
487
|
self.host.view_3d_manager.current_mol
|
|
486
488
|
),
|
|
487
489
|
"formula": rdMolDescriptors.CalcMolFormula(
|
|
@@ -620,7 +622,11 @@ class StateManager:
|
|
|
620
622
|
mol_base64 = structure_3d.get("mol_binary_base64")
|
|
621
623
|
if mol_base64:
|
|
622
624
|
mol_binary = base64.b64decode(mol_base64.encode("ascii"))
|
|
623
|
-
|
|
625
|
+
# Chem.Mol accepts a pickled binary block at runtime;
|
|
626
|
+
# the stub only overloads Mol/str.
|
|
627
|
+
self.host.set_current_molecule(
|
|
628
|
+
Chem.Mol(mol_binary) # type: ignore[call-overload]
|
|
629
|
+
)
|
|
624
630
|
if self.host.view_3d_manager.current_mol:
|
|
625
631
|
# Set 3D coordinates
|
|
626
632
|
if self.host.view_3d_manager.current_mol.GetNumConformers() > 0:
|
|
@@ -686,7 +692,7 @@ class StateManager:
|
|
|
686
692
|
self.host.set_is_2d_editable(True)
|
|
687
693
|
|
|
688
694
|
if self.host.view_3d_manager.plotter:
|
|
689
|
-
self.host.view_3d_manager.plotter.reset_camera()
|
|
695
|
+
self.host.view_3d_manager.plotter.reset_camera() # type: ignore[call-arg]
|
|
690
696
|
|
|
691
697
|
# Enable 3D-related UI
|
|
692
698
|
try:
|
|
@@ -95,18 +95,18 @@ class AtomItem(QGraphicsItem):
|
|
|
95
95
|
| QGraphicsItem.GraphicsItemFlag.ItemSendsGeometryChanges
|
|
96
96
|
)
|
|
97
97
|
self.setZValue(1)
|
|
98
|
+
self.font: QFont = QFont(FONT_FAMILY, 22, FONT_WEIGHT_BOLD)
|
|
98
99
|
self.update_style()
|
|
99
100
|
self.setAcceptHoverEvents(True)
|
|
100
101
|
self.hovered: bool = False
|
|
101
102
|
self.has_problem: bool = False
|
|
102
103
|
self.is_visible: bool = True
|
|
103
|
-
self.font: QFont = QFont(FONT_FAMILY, 20, FONT_WEIGHT_BOLD)
|
|
104
104
|
|
|
105
105
|
def update_style(self) -> None:
|
|
106
106
|
"""Refresh font, color, and visibility based on current scene settings."""
|
|
107
107
|
if sip_isdeleted_safe(self):
|
|
108
108
|
return
|
|
109
|
-
font_size =
|
|
109
|
+
font_size = 22
|
|
110
110
|
font_family = FONT_FAMILY
|
|
111
111
|
font_bold = True
|
|
112
112
|
font_italic = False
|
|
@@ -114,7 +114,7 @@ class AtomItem(QGraphicsItem):
|
|
|
114
114
|
|
|
115
115
|
scene: Any = self.scene()
|
|
116
116
|
if scene is not None:
|
|
117
|
-
font_size = scene.get_setting("atom_font_size_2d",
|
|
117
|
+
font_size = scene.get_setting("atom_font_size_2d", 22)
|
|
118
118
|
font_family = scene.get_setting("atom_font_family_2d", FONT_FAMILY)
|
|
119
119
|
font_bold = scene.get_setting("atom_font_bold_2d", True)
|
|
120
120
|
font_italic = scene.get_setting("atom_font_italic_2d", False)
|
|
@@ -136,14 +136,14 @@ class AtomItem(QGraphicsItem):
|
|
|
136
136
|
|
|
137
137
|
def visual_rect(self) -> QRectF:
|
|
138
138
|
"""Return the rectangle the atom draws into; highlights use this."""
|
|
139
|
-
font_size =
|
|
139
|
+
font_size = 22
|
|
140
140
|
font_family = FONT_FAMILY
|
|
141
141
|
font_bold = True
|
|
142
142
|
font_italic = False
|
|
143
143
|
font_underline = False
|
|
144
144
|
scene: Any = self.scene()
|
|
145
145
|
if scene is not None:
|
|
146
|
-
font_size = scene.get_setting("atom_font_size_2d",
|
|
146
|
+
font_size = scene.get_setting("atom_font_size_2d", 22)
|
|
147
147
|
font_family = scene.get_setting("atom_font_family_2d", FONT_FAMILY)
|
|
148
148
|
font_bold = scene.get_setting("atom_font_bold_2d", True)
|
|
149
149
|
font_italic = scene.get_setting("atom_font_italic_2d", False)
|
|
@@ -265,14 +265,14 @@ class AtomItem(QGraphicsItem):
|
|
|
265
265
|
if not self.is_visible:
|
|
266
266
|
return path
|
|
267
267
|
|
|
268
|
-
font_size =
|
|
268
|
+
font_size = 22
|
|
269
269
|
font_family = FONT_FAMILY
|
|
270
270
|
font_bold = True
|
|
271
271
|
font_italic = False
|
|
272
272
|
font_underline = False
|
|
273
273
|
scene: Any = self.scene()
|
|
274
274
|
if scene is not None:
|
|
275
|
-
font_size = scene.get_setting("atom_font_size_2d",
|
|
275
|
+
font_size = scene.get_setting("atom_font_size_2d", 22)
|
|
276
276
|
font_family = scene.get_setting("atom_font_family_2d", FONT_FAMILY)
|
|
277
277
|
font_bold = scene.get_setting("atom_font_bold_2d", True)
|
|
278
278
|
font_italic = scene.get_setting("atom_font_italic_2d", False)
|
{moleditpy_linux-4.8.2 → moleditpy_linux-4.9.0}/src/moleditpy_linux/ui/base_picking_dialog.py
RENAMED
|
@@ -11,7 +11,7 @@ DOI: 10.5281/zenodo.17268532
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
import logging
|
|
14
|
-
from typing import
|
|
14
|
+
from typing import Any, List, Optional, Union, TYPE_CHECKING
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
from PyQt6.QtCore import Qt, QTimer
|
|
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
25
25
|
from .main_window import MainWindow
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
class SelectionList(
|
|
28
|
+
class SelectionList(List[int]):
|
|
29
29
|
"""Order-preserving list that compares equal to sets/lists/tuples of same elements."""
|
|
30
30
|
|
|
31
31
|
def __eq__(self, other: object) -> bool:
|
|
@@ -254,7 +254,7 @@ class BondItem(QGraphicsItem):
|
|
|
254
254
|
else "bond_spacing_double_2d"
|
|
255
255
|
)
|
|
256
256
|
bond_offset = scene.get_setting(key, 3.5)
|
|
257
|
-
wedge_width = scene.get_setting("bond_wedge_width_2d",
|
|
257
|
+
wedge_width = scene.get_setting("bond_wedge_width_2d", 8.0)
|
|
258
258
|
|
|
259
259
|
# Qt prunes clicks whose shape() escapes boundingRect().
|
|
260
260
|
extra = (getattr(self, "order", 1) - 1) * bond_offset + 50 + wedge_width
|
|
@@ -270,7 +270,7 @@ class BondItem(QGraphicsItem):
|
|
|
270
270
|
font_size = 20
|
|
271
271
|
font_family = FONT_FAMILY
|
|
272
272
|
if scene is not None:
|
|
273
|
-
font_size = scene.get_setting("atom_font_size_2d",
|
|
273
|
+
font_size = scene.get_setting("atom_font_size_2d", 22)
|
|
274
274
|
font_family = scene.get_setting("atom_font_family_2d", FONT_FAMILY)
|
|
275
275
|
|
|
276
276
|
font = QFont(font_family, font_size, FONT_WEIGHT_BOLD)
|
|
@@ -363,11 +363,11 @@ class BondItem(QGraphicsItem):
|
|
|
363
363
|
bond_color = QColor(color_hex)
|
|
364
364
|
|
|
365
365
|
# Width and Cap Style
|
|
366
|
-
bond_width = scene.get_setting("bond_width_2d",
|
|
366
|
+
bond_width = scene.get_setting("bond_width_2d", 3.0)
|
|
367
367
|
cap_style_str = scene.get_setting("bond_cap_style_2d", "Round")
|
|
368
368
|
|
|
369
369
|
# Wedge/Dash settings
|
|
370
|
-
wedge_width_half = scene.get_setting("bond_wedge_width_2d",
|
|
370
|
+
wedge_width_half = scene.get_setting("bond_wedge_width_2d", 8.0)
|
|
371
371
|
num_dashes = int(scene.get_setting("bond_dash_count_2d", 8))
|
|
372
372
|
|
|
373
373
|
# Cap Style logic
|
|
@@ -531,7 +531,7 @@ class BondItem(QGraphicsItem):
|
|
|
531
531
|
font_family = FONT_FAMILY
|
|
532
532
|
_sc: Any = self.scene()
|
|
533
533
|
if _sc is not None:
|
|
534
|
-
font_size = _sc.get_setting("atom_font_size_2d",
|
|
534
|
+
font_size = _sc.get_setting("atom_font_size_2d", 22)
|
|
535
535
|
font_family = _sc.get_setting(
|
|
536
536
|
"atom_font_family_2d", FONT_FAMILY
|
|
537
537
|
)
|