MoleditPy-linux 2.0.0__tar.gz → 2.1.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-2.0.0 → moleditpy_linux-2.1.0}/PKG-INFO +1 -1
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/pyproject.toml +1 -1
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/constants.py +1 -1
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_main_init.py +38 -2
- moleditpy_linux-2.1.0/src/moleditpy_linux/modules/plugin_manager.py +120 -0
- moleditpy_linux-2.0.0/src/moleditpy_linux/modules/plugin_manager.py +0 -85
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/LICENSE +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/README.md +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/setup.cfg +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/__init__.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/__main__.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/main.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/__init__.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/about_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/align_plane_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/alignment_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/analysis_window.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/angle_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/assets/icon.icns +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/assets/icon.ico +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/assets/icon.png +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/atom_item.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/bond_item.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/bond_length_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/calculation_worker.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/color_settings_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/constrained_optimization_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/custom_interactor_style.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/custom_qt_interactor.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/dialog3_d_picking_mixin.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/dihedral_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_app_state.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_compute.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_dialog_manager.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_edit_3d.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_edit_actions.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_export.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_molecular_parsers.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_project_io.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_string_importers.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_ui_manager.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_view_3d.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_view_loaders.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/mirror_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/molecular_data.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/molecule_scene.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/move_group_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/periodic_table_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/planarize_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/settings_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/template_preview_item.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/template_preview_view.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/translation_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/user_template_dialog.py +0 -0
- {moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/zoomable_view.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.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
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_main_init.py
RENAMED
|
@@ -1214,6 +1214,8 @@ class MainWindowMainInit(object):
|
|
|
1214
1214
|
reload_plugins_action = QAction("Reload Plugins", self)
|
|
1215
1215
|
reload_plugins_action.triggered.connect(lambda: self.update_plugin_menu(plugin_menu))
|
|
1216
1216
|
plugin_menu.addAction(reload_plugins_action)
|
|
1217
|
+
|
|
1218
|
+
|
|
1217
1219
|
|
|
1218
1220
|
plugin_menu.addSeparator()
|
|
1219
1221
|
|
|
@@ -1723,19 +1725,53 @@ class MainWindowMainInit(object):
|
|
|
1723
1725
|
reload_plugins_action = QAction("Reload Plugins", self)
|
|
1724
1726
|
reload_plugins_action.triggered.connect(lambda: self.update_plugin_menu(plugin_menu))
|
|
1725
1727
|
plugin_menu.addAction(reload_plugins_action)
|
|
1728
|
+
|
|
1729
|
+
explore_plugins_action = QAction("Explore Plugins", self)
|
|
1730
|
+
explore_plugins_action.triggered.connect(
|
|
1731
|
+
lambda: QDesktopServices.openUrl(QUrl("https://github.com/HiroYokoyama/moleditpy-plugins"))
|
|
1732
|
+
)
|
|
1733
|
+
plugin_menu.addAction(explore_plugins_action)
|
|
1726
1734
|
|
|
1727
1735
|
plugin_menu.addSeparator()
|
|
1728
1736
|
|
|
1729
1737
|
# Add dynamic plugin actions
|
|
1730
1738
|
plugins = self.plugin_manager.discover_plugins(self)
|
|
1739
|
+
|
|
1731
1740
|
if not plugins:
|
|
1732
1741
|
no_plugin_action = QAction("(No plugins found)", self)
|
|
1733
1742
|
no_plugin_action.setEnabled(False)
|
|
1734
1743
|
plugin_menu.addAction(no_plugin_action)
|
|
1735
1744
|
else:
|
|
1745
|
+
# Sort plugins: directories first (to create menus), then alphabetical by name
|
|
1746
|
+
# Actually simple sort by rel_folder, name is fine
|
|
1747
|
+
plugins.sort(key=lambda x: (x.get('rel_folder', ''), x['name']))
|
|
1748
|
+
|
|
1749
|
+
# Dictionary to keep track of created submenus: path -> QMenu
|
|
1750
|
+
menus = { "": plugin_menu }
|
|
1751
|
+
|
|
1736
1752
|
for p in plugins:
|
|
1737
|
-
|
|
1753
|
+
rel_folder = p.get('rel_folder', "")
|
|
1754
|
+
|
|
1755
|
+
# Get or create the parent menu for this plugin
|
|
1756
|
+
parent_menu = menus.get("") # Start at root
|
|
1757
|
+
|
|
1758
|
+
if rel_folder:
|
|
1759
|
+
# Split path and traverse/create submenus
|
|
1760
|
+
parts = rel_folder.split(os.sep)
|
|
1761
|
+
current_path = ""
|
|
1762
|
+
for part in parts:
|
|
1763
|
+
new_path = os.path.join(current_path, part) if current_path else part
|
|
1764
|
+
|
|
1765
|
+
if new_path not in menus:
|
|
1766
|
+
# Create new submenu
|
|
1767
|
+
sub_menu = parent_menu.addMenu(part)
|
|
1768
|
+
menus[new_path] = sub_menu
|
|
1769
|
+
|
|
1770
|
+
parent_menu = menus[new_path]
|
|
1771
|
+
current_path = new_path
|
|
1772
|
+
|
|
1773
|
+
# Add action to the resolved parent_menu
|
|
1738
1774
|
action = QAction(p['name'], self)
|
|
1739
1775
|
action.triggered.connect(lambda checked, mod=p['module']: self.plugin_manager.run_plugin(mod, self.mw if hasattr(self, 'mw') else self))
|
|
1740
|
-
|
|
1776
|
+
parent_menu.addAction(action)
|
|
1741
1777
|
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
plugin_manager.py
|
|
6
|
+
Manages discovery, loading, and execution of external plugins.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
import importlib.util
|
|
12
|
+
import traceback
|
|
13
|
+
from PyQt6.QtGui import QDesktopServices
|
|
14
|
+
from PyQt6.QtCore import QUrl
|
|
15
|
+
from PyQt6.QtWidgets import QMessageBox
|
|
16
|
+
|
|
17
|
+
class PluginManager:
|
|
18
|
+
def __init__(self):
|
|
19
|
+
self.plugin_dir = os.path.join(os.path.expanduser('~'), '.moleditpy', 'plugins')
|
|
20
|
+
self.plugins = [] # List of {"name": str, "module": module_obj}
|
|
21
|
+
|
|
22
|
+
def ensure_plugin_dir(self):
|
|
23
|
+
"""Creates the plugin directory if it creates doesn't exist."""
|
|
24
|
+
if not os.path.exists(self.plugin_dir):
|
|
25
|
+
try:
|
|
26
|
+
os.makedirs(self.plugin_dir)
|
|
27
|
+
except OSError as e:
|
|
28
|
+
print(f"Error creating plugin directory: {e}")
|
|
29
|
+
|
|
30
|
+
def open_plugin_folder(self):
|
|
31
|
+
"""Opens the plugin directory in the OS file explorer."""
|
|
32
|
+
self.ensure_plugin_dir()
|
|
33
|
+
QDesktopServices.openUrl(QUrl.fromLocalFile(self.plugin_dir))
|
|
34
|
+
|
|
35
|
+
def discover_plugins(self, parent=None):
|
|
36
|
+
"""
|
|
37
|
+
Recursively scans the plugin directory for .py files and attempts to import them.
|
|
38
|
+
Ignores __pycache__ and other directories starting with "__".
|
|
39
|
+
Returns a list of valid loaded plugins.
|
|
40
|
+
"""
|
|
41
|
+
self.ensure_plugin_dir()
|
|
42
|
+
self.plugins = []
|
|
43
|
+
|
|
44
|
+
if not os.path.exists(self.plugin_dir):
|
|
45
|
+
return []
|
|
46
|
+
|
|
47
|
+
for root, dirs, files in os.walk(self.plugin_dir):
|
|
48
|
+
# Modify dirs in-place to skip hidden directories and __pycache__
|
|
49
|
+
dirs[:] = [d for d in dirs if not d.startswith('__') and d != '__pycache__']
|
|
50
|
+
|
|
51
|
+
for filename in files:
|
|
52
|
+
if filename.endswith(".py") and not filename.startswith("__"):
|
|
53
|
+
filepath = os.path.join(root, filename)
|
|
54
|
+
|
|
55
|
+
# Calculate relative folder path for menu structure
|
|
56
|
+
# equivalent to: rel_path = os.path.relpath(root, self.plugin_dir)
|
|
57
|
+
# if root is plugin_dir, rel_path is '.'
|
|
58
|
+
rel_folder = os.path.relpath(root, self.plugin_dir)
|
|
59
|
+
if rel_folder == '.':
|
|
60
|
+
rel_folder = ""
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
# Unique module name based on file path to avoid conflicts
|
|
64
|
+
# e.g. plugins.subdir.myplugin
|
|
65
|
+
module_name = os.path.splitext(os.path.relpath(filepath, self.plugin_dir))[0].replace(os.sep, '.')
|
|
66
|
+
|
|
67
|
+
spec = importlib.util.spec_from_file_location(module_name, filepath)
|
|
68
|
+
if spec and spec.loader:
|
|
69
|
+
module = importlib.util.module_from_spec(spec)
|
|
70
|
+
sys.modules[spec.name] = module
|
|
71
|
+
spec.loader.exec_module(module)
|
|
72
|
+
|
|
73
|
+
# Check for required attributes
|
|
74
|
+
plugin_name = getattr(module, 'PLUGIN_NAME', filename[:-3])
|
|
75
|
+
|
|
76
|
+
# Valid plugin if it has 'run' OR 'autorun'
|
|
77
|
+
has_run = hasattr(module, 'run') and callable(module.run)
|
|
78
|
+
has_autorun = hasattr(module, 'autorun') and callable(module.autorun)
|
|
79
|
+
|
|
80
|
+
if has_run:
|
|
81
|
+
self.plugins.append({
|
|
82
|
+
'name': plugin_name,
|
|
83
|
+
'module': module,
|
|
84
|
+
'rel_folder': rel_folder
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
if has_autorun:
|
|
88
|
+
try:
|
|
89
|
+
if parent:
|
|
90
|
+
module.autorun(parent)
|
|
91
|
+
else:
|
|
92
|
+
print(f"Skipping autorun for {plugin_name}: parent not provided.")
|
|
93
|
+
except Exception as e:
|
|
94
|
+
print(f"Error executing autorun for {filename}: {e}")
|
|
95
|
+
traceback.print_exc()
|
|
96
|
+
|
|
97
|
+
if not has_run and not has_autorun:
|
|
98
|
+
print(f"Plugin {filename} skipped: Missing 'run(main_window)' or 'autorun(main_window)' function.")
|
|
99
|
+
|
|
100
|
+
except Exception as e:
|
|
101
|
+
# Robust error handling
|
|
102
|
+
msg = f"Failed to load plugin {filename}:\n{e}"
|
|
103
|
+
print(msg)
|
|
104
|
+
traceback.print_exc()
|
|
105
|
+
if parent:
|
|
106
|
+
# Use print/status bar instead of popups for non-critical failures during bulk load?
|
|
107
|
+
# For now, keep it visible but maybe less intrusive if many fail?
|
|
108
|
+
# sticking to original logic just in catch block
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
return self.plugins
|
|
112
|
+
|
|
113
|
+
def run_plugin(self, module, main_window):
|
|
114
|
+
"""Executes the plugin's run method."""
|
|
115
|
+
try:
|
|
116
|
+
module.run(main_window)
|
|
117
|
+
except Exception as e:
|
|
118
|
+
QMessageBox.critical(main_window, "Plugin Error", f"Error running plugin '{getattr(module, 'PLUGIN_NAME', 'Unknown')}':\n{e}")
|
|
119
|
+
traceback.print_exc()
|
|
120
|
+
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
plugin_manager.py
|
|
6
|
-
Manages discovery, loading, and execution of external plugins.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import os
|
|
10
|
-
import sys
|
|
11
|
-
import importlib.util
|
|
12
|
-
import traceback
|
|
13
|
-
from PyQt6.QtGui import QDesktopServices
|
|
14
|
-
from PyQt6.QtCore import QUrl
|
|
15
|
-
from PyQt6.QtWidgets import QMessageBox
|
|
16
|
-
|
|
17
|
-
class PluginManager:
|
|
18
|
-
def __init__(self):
|
|
19
|
-
self.plugin_dir = os.path.join(os.path.expanduser('~'), '.moleditpy', 'plugins')
|
|
20
|
-
self.plugins = [] # List of {"name": str, "module": module_obj}
|
|
21
|
-
|
|
22
|
-
def ensure_plugin_dir(self):
|
|
23
|
-
"""Creates the plugin directory if it creates doesn't exist."""
|
|
24
|
-
if not os.path.exists(self.plugin_dir):
|
|
25
|
-
try:
|
|
26
|
-
os.makedirs(self.plugin_dir)
|
|
27
|
-
except OSError as e:
|
|
28
|
-
print(f"Error creating plugin directory: {e}")
|
|
29
|
-
|
|
30
|
-
def open_plugin_folder(self):
|
|
31
|
-
"""Opens the plugin directory in the OS file explorer."""
|
|
32
|
-
self.ensure_plugin_dir()
|
|
33
|
-
QDesktopServices.openUrl(QUrl.fromLocalFile(self.plugin_dir))
|
|
34
|
-
|
|
35
|
-
def discover_plugins(self, parent=None):
|
|
36
|
-
"""
|
|
37
|
-
Scans the plugin directory for .py files and attempts to import them.
|
|
38
|
-
Returns a list of valid loaded plugins.
|
|
39
|
-
"""
|
|
40
|
-
self.ensure_plugin_dir()
|
|
41
|
-
self.plugins = []
|
|
42
|
-
|
|
43
|
-
if not os.path.exists(self.plugin_dir):
|
|
44
|
-
return []
|
|
45
|
-
|
|
46
|
-
for filename in os.listdir(self.plugin_dir):
|
|
47
|
-
if filename.endswith(".py") and not filename.startswith("__"):
|
|
48
|
-
filepath = os.path.join(self.plugin_dir, filename)
|
|
49
|
-
try:
|
|
50
|
-
# Dynamically import the module
|
|
51
|
-
spec = importlib.util.spec_from_file_location(filename[:-3], filepath)
|
|
52
|
-
if spec and spec.loader:
|
|
53
|
-
module = importlib.util.module_from_spec(spec)
|
|
54
|
-
sys.modules[spec.name] = module # helper for relative imports if needed
|
|
55
|
-
spec.loader.exec_module(module)
|
|
56
|
-
|
|
57
|
-
# Check for required attributes
|
|
58
|
-
plugin_name = getattr(module, 'PLUGIN_NAME', filename[:-3])
|
|
59
|
-
|
|
60
|
-
# Validate that it has a run function
|
|
61
|
-
if hasattr(module, 'run') and callable(module.run):
|
|
62
|
-
self.plugins.append({
|
|
63
|
-
'name': plugin_name,
|
|
64
|
-
'module': module
|
|
65
|
-
})
|
|
66
|
-
else:
|
|
67
|
-
print(f"Plugin {filename} skipped: Missing 'run(main_window)' function.")
|
|
68
|
-
except Exception as e:
|
|
69
|
-
# Robust error handling with user notification
|
|
70
|
-
msg = f"Failed to load plugin {filename}:\n{e}"
|
|
71
|
-
print(msg)
|
|
72
|
-
traceback.print_exc()
|
|
73
|
-
if parent:
|
|
74
|
-
QMessageBox.warning(parent, "Plugin Load Error", msg)
|
|
75
|
-
|
|
76
|
-
return self.plugins
|
|
77
|
-
|
|
78
|
-
def run_plugin(self, module, main_window):
|
|
79
|
-
"""Executes the plugin's run method."""
|
|
80
|
-
try:
|
|
81
|
-
module.run(main_window)
|
|
82
|
-
except Exception as e:
|
|
83
|
-
QMessageBox.critical(main_window, "Plugin Error", f"Error running plugin '{getattr(module, 'PLUGIN_NAME', 'Unknown')}':\n{e}")
|
|
84
|
-
traceback.print_exc()
|
|
85
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/MoleditPy_linux.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/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
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/align_plane_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/alignment_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/analysis_window.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/assets/icon.icns
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/bond_length_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/calculation_worker.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/color_settings_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/custom_qt_interactor.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/dihedral_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_app_state.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_compute.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_edit_3d.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_export.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/main_window_view_3d.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/mirror_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/molecular_data.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/molecule_scene.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/move_group_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/periodic_table_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/planarize_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/settings_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/template_preview_item.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/template_preview_view.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/translation_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/user_template_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-2.0.0 → moleditpy_linux-2.1.0}/src/moleditpy_linux/modules/zoomable_view.py
RENAMED
|
File without changes
|