moleditpy 2.8.0a1__tar.gz → 2.8.0a2__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 (66) hide show
  1. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/PKG-INFO +1 -1
  2. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/pyproject.toml +1 -1
  3. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/MoleditPy.egg-info/PKG-INFO +1 -1
  4. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/constants.py +1 -1
  5. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_compute.py +75 -52
  6. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/LICENSE +0 -0
  7. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/README.md +0 -0
  8. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/setup.cfg +0 -0
  9. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/MoleditPy.egg-info/SOURCES.txt +0 -0
  10. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/MoleditPy.egg-info/dependency_links.txt +0 -0
  11. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/MoleditPy.egg-info/entry_points.txt +0 -0
  12. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/MoleditPy.egg-info/requires.txt +0 -0
  13. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/MoleditPy.egg-info/top_level.txt +0 -0
  14. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/__init__.py +0 -0
  15. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/__main__.py +0 -0
  16. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/assets/file_icon.ico +0 -0
  17. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/assets/icon.icns +0 -0
  18. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/assets/icon.ico +0 -0
  19. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/assets/icon.png +0 -0
  20. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/main.py +0 -0
  21. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/__init__.py +0 -0
  22. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/about_dialog.py +0 -0
  23. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/align_plane_dialog.py +0 -0
  24. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/alignment_dialog.py +0 -0
  25. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/analysis_window.py +0 -0
  26. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/angle_dialog.py +0 -0
  27. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/atom_item.py +0 -0
  28. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/bond_item.py +0 -0
  29. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/bond_length_dialog.py +0 -0
  30. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/calculation_worker.py +0 -0
  31. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/color_settings_dialog.py +0 -0
  32. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/constrained_optimization_dialog.py +0 -0
  33. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/custom_interactor_style.py +0 -0
  34. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/custom_qt_interactor.py +0 -0
  35. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/dialog3_d_picking_mixin.py +0 -0
  36. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/dihedral_dialog.py +0 -0
  37. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window.py +0 -0
  38. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_app_state.py +0 -0
  39. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_dialog_manager.py +0 -0
  40. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_edit_3d.py +0 -0
  41. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_edit_actions.py +0 -0
  42. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_export.py +0 -0
  43. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_main_init.py +0 -0
  44. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_molecular_parsers.py +0 -0
  45. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_project_io.py +0 -0
  46. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_string_importers.py +0 -0
  47. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_ui_manager.py +0 -0
  48. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_view_3d.py +0 -0
  49. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/main_window_view_loaders.py +0 -0
  50. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/mirror_dialog.py +0 -0
  51. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/mol_geometry.py +0 -0
  52. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/molecular_data.py +0 -0
  53. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/molecule_scene.py +0 -0
  54. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/move_group_dialog.py +0 -0
  55. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/periodic_table_dialog.py +0 -0
  56. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/planarize_dialog.py +0 -0
  57. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/plugin_interface.py +0 -0
  58. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/plugin_manager.py +0 -0
  59. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/plugin_manager_window.py +0 -0
  60. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/settings_dialog.py +0 -0
  61. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/sip_isdeleted_safe.py +0 -0
  62. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/template_preview_item.py +0 -0
  63. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/template_preview_view.py +0 -0
  64. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/translation_dialog.py +0 -0
  65. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/user_template_dialog.py +0 -0
  66. {moleditpy-2.8.0a1 → moleditpy-2.8.0a2}/src/moleditpy/modules/zoomable_view.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy
3
- Version: 2.8.0a1
3
+ Version: 2.8.0a2
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"
7
7
 
8
- version = "2.8.0a1"
8
+ version = "2.8.0a2"
9
9
 
10
10
  license = {file = "LICENSE"}
11
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy
3
- Version: 2.8.0a1
3
+ Version: 2.8.0a2
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 QColor, QFont
16
16
  from rdkit import Chem
17
17
 
18
18
  # Version
19
- VERSION = "2.8.0a1"
19
+ VERSION = "2.8.0a2"
20
20
 
21
21
  ATOM_RADIUS = 18
22
22
  BOND_OFFSET = 3.5
@@ -1024,17 +1024,14 @@ class MainWindowCompute(object):
1024
1024
  traceback.print_exc()
1025
1025
  if not opt_method:
1026
1026
  opt_method = getattr(self, "optimization_method", None)
1027
- # normalize common forms
1027
+ # Store the optimization method using its user-friendly UI label if available.
1028
1028
  if opt_method:
1029
- om = str(opt_method).upper()
1030
- if "MMFF94S" in om or "MMFF_RDKIT" in om:
1031
- self.last_successful_optimization_method = "MMFF94s"
1032
- elif "MMFF94" in om:
1033
- self.last_successful_optimization_method = "MMFF94"
1034
- elif "UFF" in om:
1035
- self.last_successful_optimization_method = "UFF"
1036
- else:
1037
- # store raw value otherwise
1029
+ try:
1030
+ # Look up the UI label (e.g. "MMFF94s (RDKit)") from the internal ID (e.g. "MMFF_RDKIT")
1031
+ method_key = str(opt_method).upper()
1032
+ label = self.opt3d_method_labels.get(method_key, opt_method)
1033
+ self.last_successful_optimization_method = label
1034
+ except Exception:
1038
1035
  self.last_successful_optimization_method = opt_method
1039
1036
  except Exception:
1040
1037
  # non-fatal
@@ -1203,11 +1200,18 @@ class MainWindowCompute(object):
1203
1200
  return
1204
1201
 
1205
1202
  # Clear temporary plotter content and remove calculating text if present
1203
+ # Only clear the entire plotter if we don't have an existing molecule to fall back to.
1206
1204
  try:
1207
- self.plotter.clear()
1205
+ if self.current_mol is None:
1206
+ self.plotter.clear()
1207
+ else:
1208
+ # If we have a molecule, just re-render to make sure it's drawn correctly
1209
+ # (in case partial actors were added during 'calculating' phase)
1210
+ self.plotter.render()
1208
1211
  except Exception: # pragma: no cover
1209
1212
  import traceback
1210
1213
  traceback.print_exc()
1214
+ traceback.print_exc()
1211
1215
 
1212
1216
  # Also attempt to explicitly remove the calculating text actor if it was stored
1213
1217
  try:
@@ -1282,7 +1286,7 @@ class MainWindowCompute(object):
1282
1286
  QMessageBox.StandardButton.Yes,
1283
1287
  )
1284
1288
  if reply == QMessageBox.StandardButton.Yes:
1285
- self.set_optimization_method("UFF_RDKIT")
1289
+ self._temp_optimization_method = "UFF_RDKIT"
1286
1290
  self.optimize_3d_structure()
1287
1291
  # Return immediately so the rest of the error cleanup doesn't disable buttons permanently
1288
1292
  return
@@ -1325,51 +1329,70 @@ class MainWindowCompute(object):
1325
1329
  import traceback
1326
1330
  traceback.print_exc()
1327
1331
 
1328
- # On calculation error we should NOT enable 3D-only features.
1329
- # Explicitly disable Optimize and Export so the user can't try to operate
1330
- # on an invalid or missing 3D molecule.
1331
- try:
1332
- if hasattr(self, "optimize_3d_button"):
1333
- self.optimize_3d_button.setEnabled(False)
1334
- except Exception: # pragma: no cover
1335
- import traceback
1336
- traceback.print_exc()
1332
+ # On calculation error we should NOT enable 3D-only features IF we have no molecule.
1333
+ # However, if we ALREADY had a molecule (e.g. optimization failed but previous 3D was valid),
1334
+ # we should keep them enabled.
1335
+ if self.current_mol is None:
1336
+ try:
1337
+ if hasattr(self, "optimize_3d_button"):
1338
+ self.optimize_3d_button.setEnabled(False)
1339
+ except Exception: # pragma: no cover
1340
+ import traceback
1341
+ traceback.print_exc()
1337
1342
 
1338
- try:
1339
- if hasattr(self, "export_button"):
1340
- self.export_button.setEnabled(False)
1341
- except Exception: # pragma: no cover
1342
- import traceback
1343
- traceback.print_exc()
1343
+ try:
1344
+ if hasattr(self, "export_button"):
1345
+ self.export_button.setEnabled(False)
1346
+ except Exception: # pragma: no cover
1347
+ import traceback
1348
+ traceback.print_exc()
1344
1349
 
1345
- # Keep 3D feature buttons disabled to avoid inconsistent UI state
1346
- try:
1347
- self._enable_3d_features(False)
1348
- except Exception: # pragma: no cover
1349
- import traceback
1350
- traceback.print_exc()
1350
+ # Keep 3D feature buttons disabled to avoid inconsistent UI state
1351
+ try:
1352
+ self._enable_3d_features(False)
1353
+ except Exception: # pragma: no cover
1354
+ import traceback
1355
+ traceback.print_exc()
1351
1356
 
1352
- # Keep 3D edit actions disabled (no molecule to edit)
1353
- try:
1354
- self._enable_3d_edit_actions(False)
1355
- except Exception: # pragma: no cover
1356
- import traceback
1357
- traceback.print_exc()
1357
+ # Keep 3D edit actions disabled (no molecule to edit)
1358
+ try:
1359
+ self._enable_3d_edit_actions(False)
1360
+ except Exception: # pragma: no cover
1361
+ import traceback
1362
+ traceback.print_exc()
1363
+ else:
1364
+ # We HAVE a molecule, ensure features are enabled
1365
+ try:
1366
+ self._enable_3d_features(True)
1367
+ except Exception: # pragma: no cover
1368
+ import traceback
1369
+ traceback.print_exc()
1358
1370
 
1359
- # Some menu items are explicitly disabled on error
1360
- try:
1361
- if hasattr(self, "analysis_action"):
1362
- self.analysis_action.setEnabled(False)
1363
- except Exception: # pragma: no cover
1364
- import traceback
1365
- traceback.print_exc()
1371
+ # Some menu items are explicitly disabled on error IF no molecule exists
1372
+ if self.current_mol is None:
1373
+ try:
1374
+ if hasattr(self, "analysis_action"):
1375
+ self.analysis_action.setEnabled(False)
1376
+ except Exception: # pragma: no cover
1377
+ import traceback
1378
+ traceback.print_exc()
1366
1379
 
1367
- try:
1368
- if hasattr(self, "edit_3d_action"):
1369
- self.edit_3d_action.setEnabled(False)
1370
- except Exception: # pragma: no cover
1371
- import traceback
1372
- traceback.print_exc()
1380
+ try:
1381
+ if hasattr(self, "edit_3d_action"):
1382
+ self.edit_3d_action.setEnabled(False)
1383
+ except Exception: # pragma: no cover
1384
+ import traceback
1385
+ traceback.print_exc()
1386
+ else:
1387
+ # Ensure they are enabled if we have a molecule
1388
+ try:
1389
+ if hasattr(self, "analysis_action"):
1390
+ self.analysis_action.setEnabled(True)
1391
+ if hasattr(self, "edit_3d_action"):
1392
+ self.edit_3d_action.setEnabled(True)
1393
+ except Exception: # pragma: no cover
1394
+ import traceback
1395
+ traceback.print_exc()
1373
1396
 
1374
1397
  # Force a UI refresh
1375
1398
  try:
File without changes
File without changes
File without changes