MoleditPy-linux 3.0.0__tar.gz → 3.0.2__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-3.0.0 → moleditpy_linux-3.0.2}/PKG-INFO +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/pyproject.toml +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/plugin_interface.py +44 -22
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/plugin_manager.py +0 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/app_state.py +0 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/bond_item.py +0 -7
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/custom_interactor_style.py +0 -6
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/dialog_logic.py +0 -4
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/edit_actions_logic.py +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/io_logic.py +10 -6
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/main_window.py +7 -2
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/main_window_init.py +16 -27
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/molecular_scene_handler.py +1 -3
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/molecule_scene.py +0 -4
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_dialog.py +5 -2
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +2 -4
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/ui_manager.py +0 -2
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/user_template_dialog.py +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/view_3d_logic.py +3 -3
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/zoomable_view.py +0 -3
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/utils/constants.py +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/utils/default_settings.py +1 -1
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/LICENSE +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/README.md +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/setup.cfg +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/__init__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/__main__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/assets/file_icon.ico +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/assets/icon.icns +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/assets/icon.ico +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/assets/icon.png +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/core/__init__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/core/mol_geometry.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/core/molecular_data.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/main.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/__init__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/plugin_manager_window.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/__init__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/about_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/analysis_window.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/atom_item.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/base_picking_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/calculation_worker.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/compute_logic.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/custom_qt_interactor.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/export_logic.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/move_group_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/planarize_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/sip_isdeleted_safe.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/string_importers.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/template_preview_item.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/translation_dialog.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/utils/__init__.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
- {moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/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: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
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
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/plugin_interface.py
RENAMED
|
@@ -119,12 +119,6 @@ class PluginContext:
|
|
|
119
119
|
"""
|
|
120
120
|
return Plugin3DController(self._manager.get_main_window())
|
|
121
121
|
|
|
122
|
-
def show_status_message(self, message: str, timeout: int = 3000) -> None:
|
|
123
|
-
"""
|
|
124
|
-
Display a message in the application status bar.
|
|
125
|
-
"""
|
|
126
|
-
self._manager.show_status_message(message, timeout)
|
|
127
|
-
|
|
128
122
|
def push_undo_checkpoint(self) -> None:
|
|
129
123
|
"""
|
|
130
124
|
Create an undo checkpoint for the current state.
|
|
@@ -133,18 +127,6 @@ class PluginContext:
|
|
|
133
127
|
"""
|
|
134
128
|
self._manager.push_undo_checkpoint()
|
|
135
129
|
|
|
136
|
-
def refresh_3d_view(self) -> None:
|
|
137
|
-
"""
|
|
138
|
-
Force a refresh (re-render) of the 3D scene.
|
|
139
|
-
"""
|
|
140
|
-
self._manager.refresh_3d_view()
|
|
141
|
-
|
|
142
|
-
def reset_3d_camera(self) -> None:
|
|
143
|
-
"""
|
|
144
|
-
Resets the 3D camera to fit the current molecule.
|
|
145
|
-
"""
|
|
146
|
-
self._manager.reset_3d_camera()
|
|
147
|
-
|
|
148
130
|
def get_selected_atom_indices(self) -> List[int]:
|
|
149
131
|
"""
|
|
150
132
|
Returns a list of RDKit atom indices currently selected in the 2D or 3D view.
|
|
@@ -173,21 +155,30 @@ class PluginContext:
|
|
|
173
155
|
"""
|
|
174
156
|
return self._manager.get_main_window()
|
|
175
157
|
|
|
158
|
+
def show_status_message(self, message: str, timeout: int = 3000) -> None:
|
|
159
|
+
"""
|
|
160
|
+
Display a temporary message in the status bar of the main window.
|
|
161
|
+
"""
|
|
162
|
+
self._manager.show_status_message(message, timeout)
|
|
163
|
+
|
|
176
164
|
@property
|
|
177
165
|
def current_mol(self) -> Any:
|
|
178
166
|
"""
|
|
179
167
|
Get or set the current molecule (RDKit Mol object). Shortcut for current_molecule.
|
|
180
168
|
"""
|
|
181
169
|
mw = self.get_main_window()
|
|
182
|
-
return
|
|
170
|
+
return (
|
|
171
|
+
mw.view_3d_manager.current_mol
|
|
172
|
+
if mw and hasattr(mw, "view_3d_manager")
|
|
173
|
+
else None
|
|
174
|
+
)
|
|
183
175
|
|
|
184
176
|
@current_mol.setter
|
|
185
177
|
def current_mol(self, mol: Any):
|
|
186
178
|
mw = self.get_main_window()
|
|
187
179
|
if mw and hasattr(mw, "view_3d_manager"):
|
|
188
180
|
mw.view_3d_manager.current_mol = mol
|
|
189
|
-
|
|
190
|
-
mw.view_3d_manager.draw_molecule_3d(mol)
|
|
181
|
+
mw.view_3d_manager.draw_molecule_3d(mol)
|
|
191
182
|
|
|
192
183
|
@property
|
|
193
184
|
def current_molecule(self) -> Any:
|
|
@@ -204,7 +195,11 @@ class PluginContext:
|
|
|
204
195
|
Returns the PyVista plotter from the MainWindow.
|
|
205
196
|
"""
|
|
206
197
|
mw = self.get_main_window()
|
|
207
|
-
return
|
|
198
|
+
return (
|
|
199
|
+
mw.view_3d_manager.plotter
|
|
200
|
+
if mw and hasattr(mw, "view_3d_manager")
|
|
201
|
+
else None
|
|
202
|
+
)
|
|
208
203
|
|
|
209
204
|
@property
|
|
210
205
|
def scene(self) -> Any:
|
|
@@ -214,6 +209,33 @@ class PluginContext:
|
|
|
214
209
|
mw = self.get_main_window()
|
|
215
210
|
return mw.init_manager.scene if mw and hasattr(mw, "init_manager") else None
|
|
216
211
|
|
|
212
|
+
def draw_molecule_3d(self, mol: Any) -> None:
|
|
213
|
+
"""Draw a molecule in the 3D scene (Direct manager call)."""
|
|
214
|
+
mw = self.get_main_window()
|
|
215
|
+
if mw and hasattr(mw, "view_3d_manager"):
|
|
216
|
+
mw.view_3d_manager.draw_molecule_3d(mol)
|
|
217
|
+
|
|
218
|
+
def refresh_3d_view(self) -> None:
|
|
219
|
+
"""Force the 3D window to redraw using the current molecule."""
|
|
220
|
+
mw = self.get_main_window()
|
|
221
|
+
if mw and hasattr(mw, "view_3d_manager"):
|
|
222
|
+
mol = getattr(mw.view_3d_manager, "current_mol", None)
|
|
223
|
+
if mol:
|
|
224
|
+
mw.view_3d_manager.draw_molecule_3d(mol)
|
|
225
|
+
else:
|
|
226
|
+
# Also redraw/clear plotter if no molecule
|
|
227
|
+
if (
|
|
228
|
+
hasattr(mw.view_3d_manager, "plotter")
|
|
229
|
+
and mw.view_3d_manager.plotter
|
|
230
|
+
):
|
|
231
|
+
mw.view_3d_manager.plotter.render()
|
|
232
|
+
|
|
233
|
+
def reset_3d_camera(self) -> None:
|
|
234
|
+
"""Zoom in and re-center the 3D viewport to fit the current molecule."""
|
|
235
|
+
mw = self.get_main_window()
|
|
236
|
+
if mw and hasattr(mw, "view_3d_manager") and mw.view_3d_manager.plotter:
|
|
237
|
+
mw.view_3d_manager.plotter.reset_camera()
|
|
238
|
+
|
|
217
239
|
def add_export_action(self, label: str, callback: Callable):
|
|
218
240
|
"""
|
|
219
241
|
Register a custom export action.
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/plugin_manager.py
RENAMED
|
@@ -514,7 +514,6 @@ class PluginManager:
|
|
|
514
514
|
|
|
515
515
|
# Check 2D selection
|
|
516
516
|
try:
|
|
517
|
-
from .plugin_interface import PluginContext
|
|
518
517
|
# We need to access the scene items.
|
|
519
518
|
# In MoleditPy, atoms in the scene are AtomItem objects which have an 'atom_id'.
|
|
520
519
|
# These atom_ids map to entries in state_manager.data.atoms.
|
|
@@ -752,7 +752,6 @@ class StateManager:
|
|
|
752
752
|
if self.host.view_3d_manager.current_mol:
|
|
753
753
|
# Set 3D coordinates
|
|
754
754
|
if self.host.view_3d_manager.current_mol.GetNumConformers() > 0:
|
|
755
|
-
conf = self.host.view_3d_manager.current_mol.GetConformer()
|
|
756
755
|
atoms_3d = structure_3d.get("atoms", [])
|
|
757
756
|
# Ensure numpy array size matches atoms in file
|
|
758
757
|
num_atoms_file = len(atoms_3d)
|
|
@@ -242,7 +242,6 @@ class BondItem(QGraphicsItem):
|
|
|
242
242
|
center = line.center()
|
|
243
243
|
|
|
244
244
|
# Logic similar to boundingRect but returning just the label box
|
|
245
|
-
font_size = 20
|
|
246
245
|
# ... (Simpler logic: just return a box around center)
|
|
247
246
|
# Standard size estimate
|
|
248
247
|
box_size = 30
|
|
@@ -265,7 +264,6 @@ class BondItem(QGraphicsItem):
|
|
|
265
264
|
return
|
|
266
265
|
|
|
267
266
|
# Default values
|
|
268
|
-
width_2d = 2.0
|
|
269
267
|
wedge_width_half = 6.0
|
|
270
268
|
num_dashes = 8
|
|
271
269
|
bond_color = QColor("#222222")
|
|
@@ -375,9 +373,6 @@ class BondItem(QGraphicsItem):
|
|
|
375
373
|
|
|
376
374
|
if is_in_ring and ring_center:
|
|
377
375
|
# Ring structure: 1 central line (single bond pos) + 1 short inner line
|
|
378
|
-
# Calculate direction from bond center to ring center
|
|
379
|
-
bond_center = line.center()
|
|
380
|
-
|
|
381
376
|
# Ring center direction in local coords
|
|
382
377
|
# ring_center may be QPointF (from old/legacy code) or tuple (from new decoupled core)
|
|
383
378
|
if isinstance(ring_center, (list, tuple)):
|
|
@@ -512,8 +507,6 @@ class BondItem(QGraphicsItem):
|
|
|
512
507
|
# Continue without crashing
|
|
513
508
|
|
|
514
509
|
def hoverEnterEvent(self, event: Any) -> None:
|
|
515
|
-
scene = self.scene()
|
|
516
|
-
mode = getattr(scene, "mode", "")
|
|
517
510
|
self.hovered = True
|
|
518
511
|
self.update()
|
|
519
512
|
if self.scene():
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/custom_interactor_style.py
RENAMED
|
@@ -182,11 +182,6 @@ class CustomInteractorStyle(vtkInteractorStyleTrackballCamera):
|
|
|
182
182
|
)
|
|
183
183
|
is_edit_active = mw.edit_3d_manager.is_3d_edit_mode or is_temp_mode
|
|
184
184
|
|
|
185
|
-
# Ctrl+Click for atom selection (3D edit)
|
|
186
|
-
is_ctrl_click = bool(
|
|
187
|
-
QApplication.keyboardModifiers() & Qt.KeyboardModifier.ControlModifier
|
|
188
|
-
)
|
|
189
|
-
|
|
190
185
|
# Handle measurement mode
|
|
191
186
|
if mw.edit_3d_manager.measurement_mode and mw.view_3d_manager.current_mol:
|
|
192
187
|
click_pos = self.GetInteractor().GetEventPosition()
|
|
@@ -419,7 +414,6 @@ class CustomInteractorStyle(vtkInteractorStyleTrackballCamera):
|
|
|
419
414
|
if self._is_dragging_atom and mw.dragged_atom_info is not None:
|
|
420
415
|
# Custom atom drag
|
|
421
416
|
self.is_dragging = True
|
|
422
|
-
atom_id = mw.dragged_atom_info["id"]
|
|
423
417
|
else:
|
|
424
418
|
# Delegate camera rotation to parent
|
|
425
419
|
super().OnMouseMove()
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/edit_actions_logic.py
RENAMED
|
@@ -22,7 +22,7 @@ from typing import Any, Dict, List, Optional
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
|
|
24
24
|
try:
|
|
25
|
-
from .mol_geometry import
|
|
25
|
+
from .mol_geometry import identify_valence_problems
|
|
26
26
|
except ImportError:
|
|
27
27
|
from moleditpy_linux.core.mol_geometry import identify_valence_problems
|
|
28
28
|
|
|
@@ -207,7 +207,10 @@ class IOManager:
|
|
|
207
207
|
final_mol = _process(charge_val, use_rd_determine=True)
|
|
208
208
|
break
|
|
209
209
|
except (RuntimeError, ValueError, TypeError) as e:
|
|
210
|
-
if
|
|
210
|
+
if (
|
|
211
|
+
hasattr(self.host, "statusBar")
|
|
212
|
+
and self.host.statusBar()
|
|
213
|
+
):
|
|
211
214
|
self.host.statusBar().showMessage(
|
|
212
215
|
f"Chemistry failed for charge {charge_val}: {e}. Try a different charge or skip."
|
|
213
216
|
)
|
|
@@ -502,6 +505,7 @@ class IOManager:
|
|
|
502
505
|
50, lambda: self.host.view_3d_manager.plotter.view_isometric()
|
|
503
506
|
)
|
|
504
507
|
QTimer.singleShot(100, lambda: self.host.view_3d_manager.plotter.render())
|
|
508
|
+
QTimer.singleShot(100, self.host.view_3d_manager.fit_to_view)
|
|
505
509
|
|
|
506
510
|
except FileNotFoundError:
|
|
507
511
|
self.host.statusBar().showMessage(f"File not found: {file_path}")
|
|
@@ -670,6 +674,7 @@ class IOManager:
|
|
|
670
674
|
50, lambda: self.host.view_3d_manager.plotter.view_isometric()
|
|
671
675
|
)
|
|
672
676
|
QTimer.singleShot(100, lambda: self.host.view_3d_manager.plotter.render())
|
|
677
|
+
QTimer.singleShot(100, self.host.view_3d_manager.fit_to_view)
|
|
673
678
|
except Exception as e:
|
|
674
679
|
self.host.statusBar().showMessage(f"Error loading file: {e}")
|
|
675
680
|
|
|
@@ -917,8 +922,8 @@ class IOManager:
|
|
|
917
922
|
charge = Chem.GetFormalCharge(
|
|
918
923
|
self.host.view_3d_manager.current_mol
|
|
919
924
|
)
|
|
920
|
-
except:
|
|
921
|
-
|
|
925
|
+
except Exception as e:
|
|
926
|
+
logging.warning("Could not compute formal charge: %s", e)
|
|
922
927
|
|
|
923
928
|
multiplicity = 1
|
|
924
929
|
try:
|
|
@@ -928,8 +933,8 @@ class IOManager:
|
|
|
928
933
|
)
|
|
929
934
|
+ 1
|
|
930
935
|
)
|
|
931
|
-
except:
|
|
932
|
-
|
|
936
|
+
except Exception as e:
|
|
937
|
+
logging.warning("Could not compute multiplicity: %s", e)
|
|
933
938
|
|
|
934
939
|
xyz_lines.append(
|
|
935
940
|
f"chrg = {charge} mult = {multiplicity} | Generated by MoleditPy Ver. {VERSION}"
|
|
@@ -1033,4 +1038,3 @@ def _set_mol_prop_safe(mol: Any, key: str, val: Any) -> None:
|
|
|
1033
1038
|
|
|
1034
1039
|
# Backward-compat aliases
|
|
1035
1040
|
IOManager = IOManager
|
|
1036
|
-
|
|
@@ -73,28 +73,33 @@ class MainWindow(QMainWindow):
|
|
|
73
73
|
self, initial_file=initial_file, safe_mode=safe_mode
|
|
74
74
|
)
|
|
75
75
|
|
|
76
|
-
# --- Core Proxy Properties ---
|
|
76
|
+
# --- Core Proxy Properties (Legacy Plugin Support Only. Bypassed by Core Logics) ---
|
|
77
77
|
@property
|
|
78
78
|
def current_mol(self):
|
|
79
|
+
"""Proxy for current molecule. Not for core logic use."""
|
|
79
80
|
return self.view_3d_manager.current_mol
|
|
80
81
|
|
|
81
82
|
@current_mol.setter
|
|
82
83
|
def current_mol(self, value):
|
|
84
|
+
"""Proxy for current molecule setter. Not for core logic use."""
|
|
83
85
|
self.view_3d_manager.current_mol = value
|
|
84
86
|
|
|
85
87
|
@property
|
|
86
88
|
def plotter(self):
|
|
89
|
+
"""Proxy for 3D plotter. Not for core logic use."""
|
|
87
90
|
return self.view_3d_manager.plotter
|
|
88
91
|
|
|
89
92
|
@property
|
|
90
93
|
def data(self):
|
|
94
|
+
"""Proxy for state data. Not for core logic use."""
|
|
91
95
|
return self.state_manager.data
|
|
92
96
|
|
|
93
97
|
@property
|
|
94
98
|
def scene(self):
|
|
99
|
+
"""Proxy for 2D scene. Not for core logic use."""
|
|
95
100
|
return self.init_manager.scene
|
|
96
101
|
|
|
97
102
|
def draw_molecule_3d(self, mol):
|
|
103
|
+
"""Proxy for 3D rendering. Not for core logic use."""
|
|
98
104
|
self.current_mol = mol
|
|
99
105
|
self.view_3d_manager.draw_molecule_3d(mol)
|
|
100
|
-
|
|
@@ -289,6 +289,7 @@ class MainInitManager:
|
|
|
289
289
|
self.host.io_manager.load_xyz_for_3d_viewing(file_path)
|
|
290
290
|
elif file_ext in ["pmeraw", "pmeprj"]:
|
|
291
291
|
self.host.io_manager.open_project_file(file_path=file_path)
|
|
292
|
+
QTimer.singleShot(100, self.host.view_3d_manager.fit_to_view)
|
|
292
293
|
else:
|
|
293
294
|
self.host.statusBar().showMessage(f"Unsupported file type: {file_ext}")
|
|
294
295
|
|
|
@@ -370,30 +371,28 @@ class MainInitManager:
|
|
|
370
371
|
|
|
371
372
|
modules_to_update.append(constants_mod)
|
|
372
373
|
|
|
373
|
-
for
|
|
374
|
-
|
|
374
|
+
for mod in modules_to_update:
|
|
375
|
+
mod.CPK_COLORS.clear()
|
|
375
376
|
for k, v in DEFAULT_CPK_COLORS.items():
|
|
376
|
-
|
|
377
|
-
QColor(v) if not isinstance(v, QColor) else v
|
|
378
|
-
)
|
|
377
|
+
mod.CPK_COLORS[k] = QColor(v) if not isinstance(v, QColor) else v
|
|
379
378
|
|
|
380
379
|
# Apply overrides from settings
|
|
381
380
|
for k, hexv in overrides.items():
|
|
382
381
|
if isinstance(hexv, str) and hexv:
|
|
383
|
-
|
|
382
|
+
mod.CPK_COLORS[k] = QColor(hexv)
|
|
384
383
|
|
|
385
384
|
# Rebuild the PV representation in-place too
|
|
386
|
-
if hasattr(
|
|
387
|
-
|
|
388
|
-
for k, c in
|
|
389
|
-
|
|
385
|
+
if hasattr(mod, "CPK_COLORS_PV"):
|
|
386
|
+
mod.CPK_COLORS_PV.clear()
|
|
387
|
+
for k, c in mod.CPK_COLORS.items():
|
|
388
|
+
mod.CPK_COLORS_PV[k] = [
|
|
390
389
|
c.redF(),
|
|
391
390
|
c.greenF(),
|
|
392
391
|
c.blueF(),
|
|
393
392
|
]
|
|
394
393
|
else: # [REPORT ERROR MISSING ATTRIBUTE]
|
|
395
394
|
logging.error(
|
|
396
|
-
"REPORT ERROR: Missing attribute 'CPK_COLORS_PV' on
|
|
395
|
+
"REPORT ERROR: Missing attribute 'CPK_COLORS_PV' on constants module"
|
|
397
396
|
)
|
|
398
397
|
except (AttributeError, RuntimeError, TypeError, ValueError) as e:
|
|
399
398
|
print(f"Failed to update CPK colors from settings: {e}")
|
|
@@ -489,8 +488,8 @@ class MainInitManager:
|
|
|
489
488
|
logging.error("REPORT ERROR: Missing attribute 'conv_actions' on self")
|
|
490
489
|
|
|
491
490
|
# Intermolecular interaction
|
|
492
|
-
if hasattr(self, "intermolecular_rdkit_action"):
|
|
493
|
-
self.intermolecular_rdkit_action.setChecked(
|
|
491
|
+
if hasattr(self.host, "intermolecular_rdkit_action"):
|
|
492
|
+
self.host.intermolecular_rdkit_action.setChecked(
|
|
494
493
|
self.host.init_manager.settings.get(
|
|
495
494
|
"optimize_intermolecular_interaction_rdkit", True
|
|
496
495
|
)
|
|
@@ -524,6 +523,8 @@ class MainInitManager:
|
|
|
524
523
|
self.host.init_manager.scene.setBackgroundBrush(QBrush(QColor(bg_c)))
|
|
525
524
|
for item in self.host.init_manager.scene.items():
|
|
526
525
|
with contextlib.suppress(AttributeError, RuntimeError, TypeError):
|
|
526
|
+
if type(item).__name__ not in ("AtomItem", "BondItem"):
|
|
527
|
+
continue
|
|
527
528
|
if hasattr(item, "update_style"):
|
|
528
529
|
item.update_style()
|
|
529
530
|
else: # [REPORT ERROR MISSING ATTRIBUTE]
|
|
@@ -1315,14 +1316,7 @@ class MainInitManager:
|
|
|
1315
1316
|
if key == "ball_and_stick":
|
|
1316
1317
|
action.setChecked(True)
|
|
1317
1318
|
action.triggered.connect(
|
|
1318
|
-
lambda checked=False, k=key: (
|
|
1319
|
-
self.host.view_3d_manager.set_3d_style(k),
|
|
1320
|
-
self.host.view_3d_manager.draw_molecule_3d(
|
|
1321
|
-
self.host.view_3d_manager.current_mol
|
|
1322
|
-
)
|
|
1323
|
-
if getattr(self.host.view_3d_manager, "current_mol", None)
|
|
1324
|
-
else None,
|
|
1325
|
-
)
|
|
1319
|
+
lambda checked=False, k=key: (self.host.view_3d_manager.set_3d_style(k))
|
|
1326
1320
|
)
|
|
1327
1321
|
style_menu.addAction(action)
|
|
1328
1322
|
style_group.addAction(action)
|
|
@@ -1334,12 +1328,7 @@ class MainInitManager:
|
|
|
1334
1328
|
action = QAction(style_name, self.host, checkable=True)
|
|
1335
1329
|
action.triggered.connect(
|
|
1336
1330
|
lambda checked=False, s=style_name: (
|
|
1337
|
-
self.host.view_3d_manager.set_3d_style(s)
|
|
1338
|
-
self.host.view_3d_manager.draw_molecule_3d(
|
|
1339
|
-
self.host.view_3d_manager.current_mol
|
|
1340
|
-
)
|
|
1341
|
-
if getattr(self.host.view_3d_manager, "current_mol", None)
|
|
1342
|
-
else None,
|
|
1331
|
+
self.host.view_3d_manager.set_3d_style(s)
|
|
1343
1332
|
)
|
|
1344
1333
|
)
|
|
1345
1334
|
style_menu.addAction(action)
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/molecular_scene_handler.py
RENAMED
|
@@ -733,7 +733,7 @@ class KeyboardMixin:
|
|
|
733
733
|
# Case 1: Cursor over atom/bond (one-shot placement)
|
|
734
734
|
if isinstance(item_at_cursor, (AtomItem, BondItem)):
|
|
735
735
|
# Set benzene template parameters
|
|
736
|
-
n
|
|
736
|
+
n = 6
|
|
737
737
|
points, bonds_info, existing_items = [], [], []
|
|
738
738
|
|
|
739
739
|
# Calculate placement like update_template_preview
|
|
@@ -903,7 +903,6 @@ class KeyboardMixin:
|
|
|
903
903
|
self.data.bonds[new_key] = bond_data
|
|
904
904
|
bond.atom1, bond.atom2 = bond.atom2, bond.atom1
|
|
905
905
|
bond.update_position()
|
|
906
|
-
was_reversed = True
|
|
907
906
|
else:
|
|
908
907
|
bond.order = 1
|
|
909
908
|
bond.stereo = 1
|
|
@@ -915,7 +914,6 @@ class KeyboardMixin:
|
|
|
915
914
|
self.data.bonds[new_key] = bond_data
|
|
916
915
|
bond.atom1, bond.atom2 = bond.atom2, bond.atom1
|
|
917
916
|
bond.update_position()
|
|
918
|
-
was_reversed = True
|
|
919
917
|
else:
|
|
920
918
|
bond.order = 1
|
|
921
919
|
bond.stereo = 2
|
|
@@ -32,10 +32,6 @@ except ImportError:
|
|
|
32
32
|
from moleditpy_linux.ui.bond_item import BondItem
|
|
33
33
|
from moleditpy_linux.ui.template_preview_item import TemplatePreviewItem
|
|
34
34
|
|
|
35
|
-
try:
|
|
36
|
-
from ..utils.constants import DEFAULT_BOND_LENGTH, SNAP_DISTANCE, SUM_TOLERANCE
|
|
37
|
-
except ImportError:
|
|
38
|
-
pass
|
|
39
35
|
|
|
40
36
|
try:
|
|
41
37
|
from PyQt6 import sip as _sip # type: ignore
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
MoleditPy — A Python-based molecular editing software
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
Author: Hiromichi Yokoyama
|
|
8
|
+
License: GPL-3.0 license
|
|
9
|
+
Repo: https://github.com/HiroYokoyama/python_molecular_editor
|
|
10
|
+
DOI: 10.5281/zenodo.17268532
|
|
7
11
|
"""
|
|
8
12
|
|
|
9
13
|
import logging # [REPORT ERROR MISSING ATTRIBUTE]
|
|
@@ -23,7 +27,6 @@ from .settings_tabs.settings_3d_tabs import Settings3DSceneTab, SettingsModelTab
|
|
|
23
27
|
from .settings_tabs.settings_other_tab import SettingsOtherTab
|
|
24
28
|
|
|
25
29
|
try:
|
|
26
|
-
from ..utils.constants import CPK_COLORS
|
|
27
30
|
from ..utils.default_settings import DEFAULT_SETTINGS
|
|
28
31
|
except ImportError:
|
|
29
32
|
from moleditpy_linux.utils.default_settings import DEFAULT_SETTINGS
|
|
@@ -225,8 +225,7 @@ class SettingsModelTab(SettingsTabBase):
|
|
|
225
225
|
val = settings_dict.get(f"{p}_atom_scale", 1.0)
|
|
226
226
|
self.atom_scale_slider.setValue(int(val * 100))
|
|
227
227
|
if p in ["ball_stick", "wireframe", "stick"]:
|
|
228
|
-
|
|
229
|
-
val = settings_dict.get(f"{prefix}_bond_radius", 0.1)
|
|
228
|
+
val = settings_dict.get(f"{p}_bond_radius", 0.1)
|
|
230
229
|
self.bond_radius_slider.setValue(int(val * 100))
|
|
231
230
|
|
|
232
231
|
self.db_offset_slider.setValue(
|
|
@@ -261,8 +260,7 @@ class SettingsModelTab(SettingsTabBase):
|
|
|
261
260
|
if p in ["ball_stick", "cpk"]:
|
|
262
261
|
s[f"{p}_atom_scale"] = self.atom_scale_slider.value() / 100.0
|
|
263
262
|
if p in ["ball_stick", "wireframe", "stick"]:
|
|
264
|
-
|
|
265
|
-
s[f"{prefix}_bond_radius"] = self.bond_radius_slider.value() / 100.0
|
|
263
|
+
s[f"{p}_bond_radius"] = self.bond_radius_slider.value() / 100.0
|
|
266
264
|
s[f"{p}_double_bond_offset_factor"] = self.db_offset_slider.value() / 100.0
|
|
267
265
|
s[f"{p}_triple_bond_offset_factor"] = self.tr_offset_slider.value() / 100.0
|
|
268
266
|
s[f"{p}_double_bond_radius_factor"] = self.db_radius_slider.value() / 100.0
|
|
@@ -319,7 +319,6 @@ class UIManager(QObject):
|
|
|
319
319
|
self.host.view_3d_manager.plotter.interactor.SetInteractorStyle(style)
|
|
320
320
|
self.host.view_3d_manager.plotter.interactor.Initialize()
|
|
321
321
|
|
|
322
|
-
|
|
323
322
|
def handle_drag_enter_event(self, event):
|
|
324
323
|
"""Internal handler for drag enter event (bypasses PyQt type checks in tests)."""
|
|
325
324
|
if not event.mimeData().hasUrls():
|
|
@@ -344,7 +343,6 @@ class UIManager(QObject):
|
|
|
344
343
|
|
|
345
344
|
event.ignore()
|
|
346
345
|
|
|
347
|
-
|
|
348
346
|
def handle_drop_event(self, event):
|
|
349
347
|
"""Internal handler for file drop event (bypasses PyQt type checks in tests)."""
|
|
350
348
|
urls = event.mimeData().urls()
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/user_template_dialog.py
RENAMED
|
@@ -508,7 +508,7 @@ class UserTemplateDialog(QDialog):
|
|
|
508
508
|
brush = QBrush(Qt.GlobalColor.white)
|
|
509
509
|
ellipse_x = pos.x() - ellipse_width / 2
|
|
510
510
|
ellipse_y = pos.y() - ellipse_height / 2
|
|
511
|
-
|
|
511
|
+
scene.addEllipse(
|
|
512
512
|
ellipse_x, ellipse_y, ellipse_width, ellipse_height, pen, brush
|
|
513
513
|
)
|
|
514
514
|
|
|
@@ -37,7 +37,7 @@ except (ImportError, AttributeError, TypeError):
|
|
|
37
37
|
|
|
38
38
|
try:
|
|
39
39
|
# package relative imports (preferred when running as `python -m moleditpy`)
|
|
40
|
-
from .constants import CPK_COLORS_PV,
|
|
40
|
+
from .constants import CPK_COLORS_PV, VDW_RADII, pt
|
|
41
41
|
from .template_preview_item import TemplatePreviewItem
|
|
42
42
|
except ImportError:
|
|
43
43
|
# Fallback to absolute imports for script-style execution
|
|
@@ -549,7 +549,7 @@ class View3DManager:
|
|
|
549
549
|
# Set bond radius and resolution based on style
|
|
550
550
|
if current_style == "wireframe":
|
|
551
551
|
cyl_radius = self.host.init_manager.settings.get(
|
|
552
|
-
"wireframe_bond_radius", 0.
|
|
552
|
+
"wireframe_bond_radius", 0.02
|
|
553
553
|
)
|
|
554
554
|
bond_resolution = self.host.init_manager.settings.get(
|
|
555
555
|
"wireframe_resolution", 6
|
|
@@ -935,7 +935,7 @@ class View3DManager:
|
|
|
935
935
|
)
|
|
936
936
|
elif current_style == "wireframe":
|
|
937
937
|
bond_radius = self.host.init_manager.settings.get(
|
|
938
|
-
"wireframe_bond_radius", 0.
|
|
938
|
+
"wireframe_bond_radius", 0.02
|
|
939
939
|
)
|
|
940
940
|
else:
|
|
941
941
|
bond_radius = 0.1 # Default
|
|
@@ -117,9 +117,6 @@ class ZoomableView(QGraphicsView):
|
|
|
117
117
|
# (positive for zoom-in, negative for zoom-out)
|
|
118
118
|
factor = 1.0 + event.value()
|
|
119
119
|
|
|
120
|
-
current_scale = self.transform().m11()
|
|
121
|
-
min_scale, max_scale = 0.05, 20.0
|
|
122
|
-
|
|
123
120
|
# Apply scaling if within limits
|
|
124
121
|
self.scale(factor, factor)
|
|
125
122
|
return True
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/utils/default_settings.py
RENAMED
|
@@ -35,7 +35,7 @@ DEFAULT_SETTINGS = {
|
|
|
35
35
|
"cpk_resolution": 32,
|
|
36
36
|
"cpk_colors": {},
|
|
37
37
|
# --- 3D Model Parameters (Wireframe) ---
|
|
38
|
-
"wireframe_bond_radius": 0.
|
|
38
|
+
"wireframe_bond_radius": 0.02,
|
|
39
39
|
"wireframe_resolution": 6,
|
|
40
40
|
"wireframe_double_bond_offset_factor": 3.0,
|
|
41
41
|
"wireframe_triple_bond_offset_factor": 3.0,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/MoleditPy_linux.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/plugins/plugin_manager_window.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/align_plane_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/base_picking_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/bond_length_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/calculation_worker.py
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/color_settings_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/custom_qt_interactor.py
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/geometry_base_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/periodic_table_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/settings_tabs/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/sip_isdeleted_safe.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/template_preview_item.py
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/template_preview_view.py
RENAMED
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/ui/translation_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-3.0.0 → moleditpy_linux-3.0.2}/src/moleditpy_linux/utils/sip_isdeleted_safe.py
RENAMED
|
File without changes
|
|
File without changes
|