MoleditPy 2.2.0__py3-none-any.whl → 2.2.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. moleditpy/modules/constants.py +1 -1
  2. moleditpy/modules/main_window_main_init.py +13 -31
  3. moleditpy/modules/main_window_ui_manager.py +2 -21
  4. moleditpy/modules/plugin_interface.py +10 -1
  5. moleditpy/modules/plugin_manager.py +3 -0
  6. moleditpy/plugins/Analysis/ms_spectrum_neo.py +919 -0
  7. moleditpy/plugins/File/animated_xyz_giffer.py +583 -0
  8. moleditpy/plugins/File/cube_viewer.py +689 -0
  9. moleditpy/plugins/File/gaussian_fchk_freq_analyzer.py +1148 -0
  10. moleditpy/plugins/File/mapped_cube_viewer.py +552 -0
  11. moleditpy/plugins/File/orca_out_freq_analyzer.py +1226 -0
  12. moleditpy/plugins/File/paste_xyz.py +336 -0
  13. moleditpy/plugins/Input Generator/gaussian_input_generator_neo.py +930 -0
  14. moleditpy/plugins/Input Generator/orca_input_generator_neo.py +1028 -0
  15. moleditpy/plugins/Input Generator/orca_xyz2inp_gui.py +286 -0
  16. moleditpy/plugins/Optimization/all-trans_optimizer.py +65 -0
  17. moleditpy/plugins/Optimization/complex_molecule_untangler.py +268 -0
  18. moleditpy/plugins/Optimization/conf_search.py +224 -0
  19. moleditpy/plugins/Utility/atom_colorizer.py +547 -0
  20. moleditpy/plugins/Utility/console.py +163 -0
  21. moleditpy/plugins/Utility/pubchem_ressolver.py +244 -0
  22. moleditpy/plugins/Utility/vdw_radii_overlay.py +303 -0
  23. {moleditpy-2.2.0.dist-info → moleditpy-2.2.0a1.dist-info}/METADATA +1 -1
  24. {moleditpy-2.2.0.dist-info → moleditpy-2.2.0a1.dist-info}/RECORD +28 -11
  25. {moleditpy-2.2.0.dist-info → moleditpy-2.2.0a1.dist-info}/WHEEL +0 -0
  26. {moleditpy-2.2.0.dist-info → moleditpy-2.2.0a1.dist-info}/entry_points.txt +0 -0
  27. {moleditpy-2.2.0.dist-info → moleditpy-2.2.0a1.dist-info}/licenses/LICENSE +0 -0
  28. {moleditpy-2.2.0.dist-info → moleditpy-2.2.0a1.dist-info}/top_level.txt +0 -0
@@ -16,7 +16,7 @@ from PyQt6.QtGui import QFont, QColor
16
16
  from rdkit import Chem
17
17
 
18
18
  #Version
19
- VERSION = '2.2.0'
19
+ VERSION = '2.2.0a1'
20
20
 
21
21
  ATOM_RADIUS = 18
22
22
  BOND_OFFSET = 3.5
@@ -32,7 +32,7 @@ except Exception:
32
32
  # PyQt6 Modules
33
33
  from PyQt6.QtWidgets import (
34
34
  QApplication, QWidget, QVBoxLayout, QHBoxLayout,
35
- QPushButton, QSplitter, QToolBar, QSizePolicy, QLabel, QToolButton, QMenu, QMessageBox, QFileDialog
35
+ QPushButton, QSplitter, QToolBar, QSizePolicy, QLabel, QToolButton, QMenu, QMessageBox
36
36
  )
37
37
 
38
38
  from PyQt6.QtGui import (
@@ -1901,38 +1901,20 @@ class MainWindowMainInit(object):
1901
1901
  parent_menu.addAction(action)
1902
1902
 
1903
1903
  # 4. Integrate Export Actions into Export Button and Menu
1904
- # 4. Integrate Export Actions into Export Button AND Main File->Export Menu
1905
1904
  if self.plugin_manager.export_actions:
1906
- # Find Main File -> Export menu
1907
- main_export_menu = None
1908
- for top_action in self.menuBar().actions():
1909
- if top_action.text().replace('&', '') == 'File' and top_action.menu():
1910
- for sub_action in top_action.menu().actions():
1911
- if sub_action.text().replace('&', '') == 'Export' and sub_action.menu():
1912
- main_export_menu = sub_action.menu()
1913
- break
1914
- if main_export_menu: break
1915
-
1916
- # List of menus to populate
1917
- target_menus = []
1918
1905
  if hasattr(self, 'export_button') and self.export_button.menu():
1919
- target_menus.append(self.export_button.menu())
1920
- if main_export_menu:
1921
- target_menus.append(main_export_menu)
1922
-
1923
- for menu in target_menus:
1924
- # Add separator
1925
- sep = menu.addSeparator()
1926
- sep.setData(PLUGIN_ACTION_TAG)
1927
-
1928
- for exp in self.plugin_manager.export_actions:
1929
- label = exp['label']
1930
- callback = exp['callback']
1931
-
1932
- a = QAction(label, self)
1933
- a.triggered.connect(callback)
1934
- a.setData(PLUGIN_ACTION_TAG)
1935
- menu.addAction(a)
1906
+ # Add separator
1907
+ sep = self.export_button.menu().addSeparator()
1908
+ sep.setData(PLUGIN_ACTION_TAG)
1909
+
1910
+ for exp in self.plugin_manager.export_actions:
1911
+ label = exp['label']
1912
+ callback = exp['callback']
1913
+
1914
+ a = QAction(label, self)
1915
+ a.triggered.connect(callback)
1916
+ a.setData(PLUGIN_ACTION_TAG)
1917
+ self.export_button.menu().addAction(a)
1936
1918
 
1937
1919
  # 5. Integrate File Openers into Import Menu
1938
1920
  if hasattr(self, 'import_menu') and self.plugin_manager.file_openers:
@@ -298,7 +298,7 @@ class MainWindowUiManager(object):
298
298
 
299
299
 
300
300
  def dragEnterEvent(self, event):
301
- """ウィンドウ全体でサポートされているファイルのドラッグを受け入れる"""
301
+ """ウィンドウ全体で .pmeraw、.pmeprj、.mol、.sdf、.xyz ファイルのドラッグを受け入れる"""
302
302
  # Accept if any dragged local file has a supported extension
303
303
  if event.mimeData().hasUrls():
304
304
  urls = event.mimeData().urls()
@@ -306,28 +306,9 @@ class MainWindowUiManager(object):
306
306
  try:
307
307
  if url.isLocalFile():
308
308
  file_path = url.toLocalFile()
309
- file_lower = file_path.lower()
310
-
311
- # Built-in extensions
312
- if file_lower.endswith(('.pmeraw', '.pmeprj', '.mol', '.sdf', '.xyz')):
309
+ if file_path.lower().endswith(('.pmeraw', '.pmeprj', '.mol', '.sdf', '.xyz')):
313
310
  event.acceptProposedAction()
314
311
  return
315
-
316
- # Plugin-registered file openers
317
- if self.plugin_manager and hasattr(self.plugin_manager, 'file_openers'):
318
- for ext in self.plugin_manager.file_openers.keys():
319
- if file_lower.endswith(ext):
320
- event.acceptProposedAction()
321
- return
322
-
323
- # Plugin drop handlers (accept more liberally for custom logic)
324
- # A plugin drop handler might handle it, so accept
325
- if self.plugin_manager and hasattr(self.plugin_manager, 'drop_handlers'):
326
- if len(self.plugin_manager.drop_handlers) > 0:
327
- # Accept any file if drop handlers are registered
328
- # They will check the file type in dropEvent
329
- event.acceptProposedAction()
330
- return
331
312
  except Exception:
332
313
  continue
333
314
  event.ignore()
@@ -159,7 +159,16 @@ class PluginContext:
159
159
  self._manager.register_3d_style(self._plugin_name, style_name, callback)
160
160
 
161
161
 
162
-
162
+ def add_panel_button(self, text: str, callback: Callable, panel: str = "right"):
163
+ """
164
+ Add a button to the bottom control panel.
165
+
166
+ Args:
167
+ text: Label on the button.
168
+ callback: Function to call on click.
169
+ panel: "left" (2D Editor) or "right" (3D Viewer). Default "right".
170
+ """
171
+ self._manager.register_panel_button(self._plugin_name, text, callback, panel)
163
172
 
164
173
 
165
174
 
@@ -40,6 +40,7 @@ class PluginManager:
40
40
  # Registries for actions
41
41
  self.menu_actions = [] # List of (plugin_name, path, callback, text, icon, shortcut)
42
42
  self.toolbar_actions = []
43
+ self.context_menu_3d_actions = []
43
44
  self.drop_handlers = [] # List of (priority, plugin_name, callback)
44
45
 
45
46
  # Extended Registries (Added to prevent lazy initialization "monkey patching")
@@ -48,6 +49,7 @@ class PluginManager:
48
49
  self.file_openers = {}
49
50
  self.analysis_tools = []
50
51
  self.save_handlers = {}
52
+ self.save_handlers = {}
51
53
  self.load_handlers = {}
52
54
  self.custom_3d_styles = {} # style_name -> {'plugin': name, 'callback': func}
53
55
 
@@ -96,6 +98,7 @@ class PluginManager:
96
98
  self.plugins = []
97
99
  self.menu_actions = []
98
100
  self.toolbar_actions = []
101
+ self.context_menu_3d_actions = []
99
102
  self.drop_handlers = []
100
103
 
101
104
  # Clear extended registries