MoleditPy 2.2.0a0__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.
- moleditpy/modules/constants.py +1 -1
- moleditpy/modules/main_window_main_init.py +73 -103
- moleditpy/modules/plugin_manager.py +10 -0
- moleditpy/plugins/Analysis/ms_spectrum_neo.py +919 -0
- moleditpy/plugins/File/animated_xyz_giffer.py +583 -0
- moleditpy/plugins/File/cube_viewer.py +689 -0
- moleditpy/plugins/File/gaussian_fchk_freq_analyzer.py +1148 -0
- moleditpy/plugins/File/mapped_cube_viewer.py +552 -0
- moleditpy/plugins/File/orca_out_freq_analyzer.py +1226 -0
- moleditpy/plugins/File/paste_xyz.py +336 -0
- moleditpy/plugins/Input Generator/gaussian_input_generator_neo.py +930 -0
- moleditpy/plugins/Input Generator/orca_input_generator_neo.py +1028 -0
- moleditpy/plugins/Input Generator/orca_xyz2inp_gui.py +286 -0
- moleditpy/plugins/Optimization/all-trans_optimizer.py +65 -0
- moleditpy/plugins/Optimization/complex_molecule_untangler.py +268 -0
- moleditpy/plugins/Optimization/conf_search.py +224 -0
- moleditpy/plugins/Utility/atom_colorizer.py +547 -0
- moleditpy/plugins/Utility/console.py +163 -0
- moleditpy/plugins/Utility/pubchem_ressolver.py +244 -0
- moleditpy/plugins/Utility/vdw_radii_overlay.py +303 -0
- {moleditpy-2.2.0a0.dist-info → moleditpy-2.2.0a1.dist-info}/METADATA +1 -1
- {moleditpy-2.2.0a0.dist-info → moleditpy-2.2.0a1.dist-info}/RECORD +26 -9
- {moleditpy-2.2.0a0.dist-info → moleditpy-2.2.0a1.dist-info}/WHEEL +0 -0
- {moleditpy-2.2.0a0.dist-info → moleditpy-2.2.0a1.dist-info}/entry_points.txt +0 -0
- {moleditpy-2.2.0a0.dist-info → moleditpy-2.2.0a1.dist-info}/licenses/LICENSE +0 -0
- {moleditpy-2.2.0a0.dist-info → moleditpy-2.2.0a1.dist-info}/top_level.txt +0 -0
moleditpy/modules/constants.py
CHANGED
|
@@ -1755,10 +1755,32 @@ class MainWindowMainInit(object):
|
|
|
1755
1755
|
"""Discovers plugins and updates the plugin menu actions."""
|
|
1756
1756
|
if not self.plugin_manager:
|
|
1757
1757
|
return
|
|
1758
|
+
|
|
1759
|
+
PLUGIN_ACTION_TAG = "plugin_managed"
|
|
1760
|
+
|
|
1761
|
+
# Helper to clear tagged actions from a menu
|
|
1762
|
+
def clear_plugin_actions(menu):
|
|
1763
|
+
if not menu: return
|
|
1764
|
+
for act in list(menu.actions()):
|
|
1765
|
+
if act.data() == PLUGIN_ACTION_TAG:
|
|
1766
|
+
menu.removeAction(act)
|
|
1767
|
+
# Recurse into submenus to clean deep actions
|
|
1768
|
+
elif act.menu():
|
|
1769
|
+
clear_plugin_actions(act.menu())
|
|
1758
1770
|
|
|
1759
|
-
# Clear existing plugin actions
|
|
1771
|
+
# Clear existing plugin actions from main Plugin menu
|
|
1760
1772
|
plugin_menu.clear()
|
|
1761
1773
|
|
|
1774
|
+
# Clear tagged actions from ALL top-level menus in the Menu Bar
|
|
1775
|
+
# This ensures we catch actions added to standard menus (File, Edit) OR custom menus
|
|
1776
|
+
for top_action in self.menuBar().actions():
|
|
1777
|
+
if top_action.menu():
|
|
1778
|
+
clear_plugin_actions(top_action.menu())
|
|
1779
|
+
|
|
1780
|
+
# Clear Export menu (if button exists)
|
|
1781
|
+
if hasattr(self, 'export_button') and self.export_button.menu():
|
|
1782
|
+
clear_plugin_actions(self.export_button.menu())
|
|
1783
|
+
|
|
1762
1784
|
# Only keep the Manager action
|
|
1763
1785
|
manage_plugins_action = QAction("Plugin Manager...", self)
|
|
1764
1786
|
def show_plugin_manager():
|
|
@@ -1814,9 +1836,9 @@ class MainWindowMainInit(object):
|
|
|
1814
1836
|
action_text = text if text else parts[-1]
|
|
1815
1837
|
action = QAction(action_text, self)
|
|
1816
1838
|
action.triggered.connect(callback)
|
|
1839
|
+
action.setData(PLUGIN_ACTION_TAG) # TAG THE ACTION
|
|
1817
1840
|
current_menu.addAction(action)
|
|
1818
1841
|
|
|
1819
|
-
# 2. Add Toolbar Buttons (New System)
|
|
1820
1842
|
# 2. Add Toolbar Buttons (New System)
|
|
1821
1843
|
# Use dedicated plugin toolbar
|
|
1822
1844
|
if hasattr(self, 'plugin_toolbar'):
|
|
@@ -1840,14 +1862,12 @@ class MainWindowMainInit(object):
|
|
|
1840
1862
|
self.plugin_toolbar.hide()
|
|
1841
1863
|
|
|
1842
1864
|
# 3. Legacy Menu Building (Folder based)
|
|
1843
|
-
|
|
1844
1865
|
if not plugins:
|
|
1845
1866
|
no_plugin_action = QAction("(No plugins found)", self)
|
|
1846
1867
|
no_plugin_action.setEnabled(False)
|
|
1847
1868
|
plugin_menu.addAction(no_plugin_action)
|
|
1848
1869
|
else:
|
|
1849
1870
|
# Sort plugins: directories first (to create menus), then alphabetical by name
|
|
1850
|
-
# Actually simple sort by rel_folder, name is fine
|
|
1851
1871
|
plugins.sort(key=lambda x: (x.get('rel_folder', ''), x['name']))
|
|
1852
1872
|
|
|
1853
1873
|
# Dictionary to keep track of created submenus: path -> QMenu
|
|
@@ -1855,7 +1875,6 @@ class MainWindowMainInit(object):
|
|
|
1855
1875
|
|
|
1856
1876
|
for p in plugins:
|
|
1857
1877
|
# Only add legacy plugins (with 'run' function) to the generic Plugins menu.
|
|
1858
|
-
# New plugins (with 'initialize') should register their own menu actions if needed.
|
|
1859
1878
|
if hasattr(p['module'], 'run'):
|
|
1860
1879
|
rel_folder = p.get('rel_folder', '')
|
|
1861
1880
|
# Get or create the parent menu for this plugin
|
|
@@ -1883,113 +1902,64 @@ class MainWindowMainInit(object):
|
|
|
1883
1902
|
|
|
1884
1903
|
# 4. Integrate Export Actions into Export Button and Menu
|
|
1885
1904
|
if self.plugin_manager.export_actions:
|
|
1886
|
-
# Add separator if we have custom exports (and haven't added it yet for this session/update)
|
|
1887
|
-
# Since update_plugin_menu clears the dynamic plugin actions but NOT the export menu (which is on a button),
|
|
1888
|
-
# we need to be careful not to duplicate.
|
|
1889
|
-
# Ideally, we should clear custom actions from the export menu first.
|
|
1890
|
-
# For simplicity, we'll just check existence.
|
|
1891
|
-
|
|
1892
1905
|
if hasattr(self, 'export_button') and self.export_button.menu():
|
|
1893
|
-
#
|
|
1894
|
-
|
|
1895
|
-
|
|
1906
|
+
# Add separator
|
|
1907
|
+
sep = self.export_button.menu().addSeparator()
|
|
1908
|
+
sep.setData(PLUGIN_ACTION_TAG)
|
|
1896
1909
|
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
# ... (Refer to existing code for menu building, skipped here for brevity)
|
|
1906
|
-
pass
|
|
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)
|
|
1907
1918
|
|
|
1908
1919
|
# 5. Integrate File Openers into Import Menu
|
|
1909
1920
|
if hasattr(self, 'import_menu') and self.plugin_manager.file_openers:
|
|
1910
|
-
# Add
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1921
|
+
# Add separator
|
|
1922
|
+
sep = self.import_menu.addSeparator()
|
|
1923
|
+
sep.setData(PLUGIN_ACTION_TAG)
|
|
1924
|
+
|
|
1915
1925
|
for ext, info in self.plugin_manager.file_openers.items():
|
|
1916
|
-
# ext e.g. .xyz
|
|
1917
|
-
# info = {'plugin': name, 'callback': cb}
|
|
1918
1926
|
label = f"Import {ext} ({info.get('plugin', 'Plugin')})..."
|
|
1919
1927
|
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
callback(fpath)
|
|
1937
|
-
self.current_file_path = fpath # Update current file path?
|
|
1938
|
-
self.update_window_title()
|
|
1939
|
-
return _cb
|
|
1940
|
-
|
|
1941
|
-
a = QAction(label, self)
|
|
1942
|
-
a.triggered.connect(make_cb(info['callback']))
|
|
1943
|
-
self.import_menu.addAction(a)
|
|
1928
|
+
def make_cb(callback):
|
|
1929
|
+
def _cb():
|
|
1930
|
+
fpath, _ = QFileDialog.getOpenFileName(
|
|
1931
|
+
self, f"Import {ext}", "",
|
|
1932
|
+
f"{info.get('plugin', 'Plugin')} File (*{ext});;All Files (*)"
|
|
1933
|
+
)
|
|
1934
|
+
if fpath:
|
|
1935
|
+
callback(fpath)
|
|
1936
|
+
self.current_file_path = fpath
|
|
1937
|
+
self.update_window_title()
|
|
1938
|
+
return _cb
|
|
1939
|
+
|
|
1940
|
+
a = QAction(label, self)
|
|
1941
|
+
a.triggered.connect(make_cb(info['callback']))
|
|
1942
|
+
a.setData(PLUGIN_ACTION_TAG)
|
|
1943
|
+
self.import_menu.addAction(a)
|
|
1944
1944
|
|
|
1945
1945
|
# 6. Integrate Analysis Tools into Analysis Menu
|
|
1946
|
-
if
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1946
|
+
# Find Analysis menu again as it might not be defined if cleanup block was generic
|
|
1947
|
+
analysis_menu = None
|
|
1948
|
+
for action in self.menuBar().actions():
|
|
1949
|
+
if action.text().replace('&', '') == 'Analysis':
|
|
1950
|
+
analysis_menu = action.menu()
|
|
1951
|
+
break
|
|
1952
|
+
|
|
1953
|
+
if analysis_menu and self.plugin_manager.analysis_tools:
|
|
1954
|
+
# Add separator
|
|
1955
|
+
sep = analysis_menu.addSeparator()
|
|
1956
|
+
sep.setData(PLUGIN_ACTION_TAG)
|
|
1951
1957
|
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
if analysis_menu:
|
|
1960
|
-
# Add separator if we have plugins
|
|
1961
|
-
if self.plugin_manager.analysis_tools:
|
|
1962
|
-
analysis_menu.addSeparator()
|
|
1963
|
-
|
|
1964
|
-
for tool in self.plugin_manager.analysis_tools:
|
|
1965
|
-
label = f"{tool['label']} ({tool.get('plugin', 'Plugin')})"
|
|
1966
|
-
# duplicate check
|
|
1967
|
-
exists = False
|
|
1968
|
-
for act in analysis_menu.actions():
|
|
1969
|
-
if act.text() == label:
|
|
1970
|
-
exists = True
|
|
1971
|
-
break
|
|
1972
|
-
if not exists:
|
|
1973
|
-
a = QAction(label, self)
|
|
1974
|
-
a.triggered.connect(tool['callback'])
|
|
1975
|
-
analysis_menu.addAction(a)
|
|
1976
|
-
|
|
1977
|
-
# 7. Integrate Export Actions (Continued)
|
|
1978
|
-
if self.plugin_manager.export_actions:
|
|
1979
|
-
for exp in self.plugin_manager.export_actions:
|
|
1980
|
-
label = exp['label']
|
|
1981
|
-
callback = exp['callback']
|
|
1982
|
-
|
|
1983
|
-
exists = False
|
|
1984
|
-
for act in self.export_button.menu().actions():
|
|
1985
|
-
if act.text() == label:
|
|
1986
|
-
exists = True
|
|
1987
|
-
break
|
|
1988
|
-
|
|
1989
|
-
if not exists:
|
|
1990
|
-
a = QAction(label, self)
|
|
1991
|
-
a.triggered.connect(callback)
|
|
1992
|
-
self.export_button.menu().addAction(a)
|
|
1993
|
-
|
|
1994
|
-
# 5. Integrate File Openers (Implicitly handled during file load) uses PluginManager directly
|
|
1958
|
+
for tool in self.plugin_manager.analysis_tools:
|
|
1959
|
+
label = f"{tool['label']} ({tool.get('plugin', 'Plugin')})"
|
|
1960
|
+
|
|
1961
|
+
a = QAction(label, self)
|
|
1962
|
+
a.triggered.connect(tool['callback'])
|
|
1963
|
+
a.setData(PLUGIN_ACTION_TAG)
|
|
1964
|
+
analysis_menu.addAction(a)
|
|
1995
1965
|
|
|
@@ -98,8 +98,18 @@ class PluginManager:
|
|
|
98
98
|
self.plugins = []
|
|
99
99
|
self.menu_actions = []
|
|
100
100
|
self.toolbar_actions = []
|
|
101
|
+
self.context_menu_3d_actions = []
|
|
101
102
|
self.drop_handlers = []
|
|
102
103
|
|
|
104
|
+
# Clear extended registries
|
|
105
|
+
self.export_actions = []
|
|
106
|
+
self.optimization_methods = {}
|
|
107
|
+
self.file_openers = {}
|
|
108
|
+
self.analysis_tools = []
|
|
109
|
+
self.save_handlers = {}
|
|
110
|
+
self.load_handlers = {}
|
|
111
|
+
self.custom_3d_styles = {}
|
|
112
|
+
|
|
103
113
|
if not os.path.exists(self.plugin_dir):
|
|
104
114
|
return []
|
|
105
115
|
|