MoleditPy-linux 4.9.3__tar.gz → 4.10.1__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-4.9.3 → moleditpy_linux-4.10.1}/PKG-INFO +1 -1
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/pyproject.toml +1 -1
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/plugins/plugin_manager.py +72 -2
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/plugins/plugin_manager_window.py +61 -5
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/main_window_init.py +0 -1
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/plugin_menu_manager.py +0 -1
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/LICENSE +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/README.md +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/setup.cfg +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/__init__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/__main__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/assets/file_icon.ico +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/assets/icon.icns +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/assets/icon.ico +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/assets/icon.png +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/core/__init__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/core/mol_geometry.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/core/molecular_data.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/main.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/plugins/__init__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/plugins/plugin_interface.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/__init__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/about_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/analysis_window.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/app_state.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/atom_item.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/atom_picking.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/base_picking_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/bond_item.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/calculation_worker.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/chain_mixin.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/compute_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/custom_interactor_style.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/custom_qt_interactor.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/dialog_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/edit_actions_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/export_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/io_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/main_window.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/molecular_scene_handler.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/molecule_scene.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/move_group_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/move_selected_atoms_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/planarize_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/preview_molecule.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/settings_2d_cleanup_tab.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/string_importers.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/template_preview_item.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/translation_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/ui_manager.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/user_template_dialog.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/view_3d_logic.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/zoomable_view.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/__init__.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/constants.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/default_settings.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/hit_radius.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/suppress_log.py +0 -0
- {moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/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: 4.
|
|
3
|
+
Version: 4.10.1
|
|
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: 4.
|
|
3
|
+
Version: 4.10.1
|
|
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-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/plugins/plugin_manager.py
RENAMED
|
@@ -14,6 +14,7 @@ from __future__ import annotations
|
|
|
14
14
|
import ast
|
|
15
15
|
import hashlib
|
|
16
16
|
import importlib.util
|
|
17
|
+
import json
|
|
17
18
|
import logging
|
|
18
19
|
import os
|
|
19
20
|
import shutil
|
|
@@ -80,6 +81,10 @@ class PluginManager:
|
|
|
80
81
|
self.plugin_dir: str = os.path.join(
|
|
81
82
|
os.path.expanduser("~"), ".moleditpy", "plugins"
|
|
82
83
|
)
|
|
84
|
+
self.disabled_plugins_path: str = os.path.join(
|
|
85
|
+
os.path.expanduser("~"), ".moleditpy", "disabled_plugins.json"
|
|
86
|
+
)
|
|
87
|
+
self.disabled_plugins: set[str] = self._read_disabled_plugins()
|
|
83
88
|
self.plugins: List[Dict[str, Any]] = [] # List of dicts
|
|
84
89
|
self.main_window: Any = main_window
|
|
85
90
|
|
|
@@ -118,6 +123,42 @@ class PluginManager:
|
|
|
118
123
|
except OSError as e:
|
|
119
124
|
logging.warning(f"Error creating plugin directory: {e}")
|
|
120
125
|
|
|
126
|
+
def _read_disabled_plugins(self) -> set[str]:
|
|
127
|
+
"""Read disabled plugin paths without making a malformed file fatal."""
|
|
128
|
+
try:
|
|
129
|
+
with open(self.disabled_plugins_path, "r", encoding="utf-8") as file:
|
|
130
|
+
data = json.load(file)
|
|
131
|
+
if isinstance(data, list):
|
|
132
|
+
values = data
|
|
133
|
+
elif isinstance(data, dict) and isinstance(
|
|
134
|
+
data.get("disabled_plugins"), list
|
|
135
|
+
):
|
|
136
|
+
values = data["disabled_plugins"]
|
|
137
|
+
else:
|
|
138
|
+
values = []
|
|
139
|
+
return {str(value).replace("\\", "/") for value in values if value}
|
|
140
|
+
except (OSError, TypeError, ValueError, json.JSONDecodeError):
|
|
141
|
+
return set()
|
|
142
|
+
|
|
143
|
+
def save_disabled_plugins(self, disabled_paths: set[str]) -> None:
|
|
144
|
+
"""Persist disabled plugin paths for the next application launch."""
|
|
145
|
+
normalized = sorted(path.replace("\\", "/") for path in disabled_paths if path)
|
|
146
|
+
try:
|
|
147
|
+
os.makedirs(os.path.dirname(self.disabled_plugins_path), exist_ok=True)
|
|
148
|
+
with open(self.disabled_plugins_path, "w", encoding="utf-8") as file:
|
|
149
|
+
json.dump(normalized, file, indent=2, ensure_ascii=False)
|
|
150
|
+
self.disabled_plugins = set(normalized)
|
|
151
|
+
except (OSError, TypeError, ValueError):
|
|
152
|
+
logging.warning("Unable to save disabled plugin list", exc_info=True)
|
|
153
|
+
|
|
154
|
+
def plugin_path_key(self, filepath: str) -> str:
|
|
155
|
+
"""Return the stable, portable key used in the disabled-plugin file."""
|
|
156
|
+
return os.path.relpath(filepath, self.plugin_dir).replace("\\", "/")
|
|
157
|
+
|
|
158
|
+
def is_plugin_disabled(self, filepath: str) -> bool:
|
|
159
|
+
"""Return whether *filepath* is disabled in the current settings."""
|
|
160
|
+
return self.plugin_path_key(filepath) in self.disabled_plugins
|
|
161
|
+
|
|
121
162
|
def open_plugin_folder(self) -> None:
|
|
122
163
|
"""Opens the plugin directory in the OS file explorer."""
|
|
123
164
|
self.ensure_plugin_dir()
|
|
@@ -237,6 +278,7 @@ class PluginManager:
|
|
|
237
278
|
self.main_window = parent
|
|
238
279
|
|
|
239
280
|
self.ensure_plugin_dir()
|
|
281
|
+
self.disabled_plugins = self._read_disabled_plugins()
|
|
240
282
|
self.plugins = []
|
|
241
283
|
# Clear registries
|
|
242
284
|
self.menu_actions = []
|
|
@@ -276,7 +318,10 @@ class PluginManager:
|
|
|
276
318
|
# Module name is the folder name
|
|
277
319
|
module_name = os.path.basename(root)
|
|
278
320
|
|
|
279
|
-
self.
|
|
321
|
+
if self.is_plugin_disabled(entry_point):
|
|
322
|
+
self._register_disabled_plugin(entry_point, module_name, category)
|
|
323
|
+
else:
|
|
324
|
+
self._load_single_plugin(entry_point, module_name, category)
|
|
280
325
|
|
|
281
326
|
else:
|
|
282
327
|
# === Case 2: Category Folder (Load individual .py files) ===
|
|
@@ -290,10 +335,35 @@ class PluginManager:
|
|
|
290
335
|
entry_point = os.path.join(root, filename)
|
|
291
336
|
module_name = os.path.splitext(filename)[0]
|
|
292
337
|
|
|
293
|
-
self.
|
|
338
|
+
if self.is_plugin_disabled(entry_point):
|
|
339
|
+
self._register_disabled_plugin(
|
|
340
|
+
entry_point, module_name, category
|
|
341
|
+
)
|
|
342
|
+
else:
|
|
343
|
+
self._load_single_plugin(entry_point, module_name, category)
|
|
294
344
|
|
|
295
345
|
return self.plugins
|
|
296
346
|
|
|
347
|
+
def _register_disabled_plugin(
|
|
348
|
+
self, filepath: str, module_name: str, category: str
|
|
349
|
+
) -> None:
|
|
350
|
+
"""Add a disabled plugin without importing or initializing its code."""
|
|
351
|
+
info = self.get_plugin_info_safe(filepath)
|
|
352
|
+
self.plugins.append(
|
|
353
|
+
{
|
|
354
|
+
"name": info.get("name", module_name),
|
|
355
|
+
"version": info.get("version", "Unknown"),
|
|
356
|
+
"author": info.get("author", "Unknown"),
|
|
357
|
+
"description": info.get("description", ""),
|
|
358
|
+
"module": None,
|
|
359
|
+
"category": category or info.get("category", ""),
|
|
360
|
+
"status": "Disabled",
|
|
361
|
+
"filepath": filepath,
|
|
362
|
+
"has_run": False,
|
|
363
|
+
"disabled": True,
|
|
364
|
+
}
|
|
365
|
+
)
|
|
366
|
+
|
|
297
367
|
def _load_single_plugin(
|
|
298
368
|
self, filepath: str, module_name: str, category: str
|
|
299
369
|
) -> None:
|
|
@@ -20,6 +20,7 @@ from PyQt6.QtCore import Qt, QUrl
|
|
|
20
20
|
from PyQt6.QtGui import QDesktopServices, QDragEnterEvent, QDropEvent
|
|
21
21
|
from PyQt6.QtWidgets import (
|
|
22
22
|
QAbstractItemView,
|
|
23
|
+
QCheckBox,
|
|
23
24
|
QDialog,
|
|
24
25
|
QHBoxLayout,
|
|
25
26
|
QHeaderView,
|
|
@@ -42,6 +43,7 @@ class PluginManagerWindow(QDialog):
|
|
|
42
43
|
self.btn_remove: Any = None
|
|
43
44
|
self.table: Any = None
|
|
44
45
|
self.plugin_manager = plugin_manager
|
|
46
|
+
self._preferences_applied = False
|
|
45
47
|
self.setWindowTitle("Plugin Manager")
|
|
46
48
|
self.resize(800, 500)
|
|
47
49
|
self.setAcceptDrops(True) # Enable drag & drop for the whole window
|
|
@@ -53,7 +55,9 @@ class PluginManagerWindow(QDialog):
|
|
|
53
55
|
"""Build the plugin manager UI with table, buttons, and drag-and-drop support."""
|
|
54
56
|
layout = QVBoxLayout(self)
|
|
55
57
|
|
|
56
|
-
lbl_info = QLabel(
|
|
58
|
+
lbl_info = QLabel(
|
|
59
|
+
"Drag & Drop .py or .zip files here to install plugins. Use the checkbox to enable/disable plugins."
|
|
60
|
+
)
|
|
57
61
|
lbl_info.setStyleSheet("color: gray; font-style: italic;")
|
|
58
62
|
layout.addWidget(lbl_info)
|
|
59
63
|
|
|
@@ -73,6 +77,7 @@ class PluginManagerWindow(QDialog):
|
|
|
73
77
|
5, QHeaderView.ResizeMode.Stretch
|
|
74
78
|
) # Description stretches
|
|
75
79
|
self.table.setColumnWidth(1, 200) # Make Name column wider
|
|
80
|
+
self.table.setColumnWidth(0, 120) # Keep the status checkbox on one line
|
|
76
81
|
self.table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
|
77
82
|
self.table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
|
|
78
83
|
self.table.itemSelectionChanged.connect(self.update_button_state)
|
|
@@ -117,9 +122,17 @@ class PluginManagerWindow(QDialog):
|
|
|
117
122
|
|
|
118
123
|
self.table.setRowCount(len(plugins))
|
|
119
124
|
for row, p in enumerate(plugins):
|
|
120
|
-
|
|
121
|
-
status_item
|
|
125
|
+
# Keep an empty item for row selection; the checkbox owns visible status text.
|
|
126
|
+
status_item = QTableWidgetItem()
|
|
122
127
|
self.table.setItem(row, 0, status_item)
|
|
128
|
+
|
|
129
|
+
# Use an explicit widget so macOS keeps the checkbox and status text
|
|
130
|
+
# in a stable horizontal layout instead of stacking the item indicator.
|
|
131
|
+
status_checkbox = QCheckBox(str(p.get("status", "Unknown")))
|
|
132
|
+
status_checkbox.setChecked(not p.get("disabled", False))
|
|
133
|
+
status_checkbox.setToolTip("Enable or disable this plugin")
|
|
134
|
+
status_checkbox.setStyleSheet("QCheckBox { padding-left: 4px; }")
|
|
135
|
+
self.table.setCellWidget(row, 0, status_checkbox)
|
|
123
136
|
self.table.setItem(row, 1, QTableWidgetItem(str(p.get("name", "Unknown"))))
|
|
124
137
|
self.table.setItem(row, 2, QTableWidgetItem(str(p.get("version", ""))))
|
|
125
138
|
self.table.setItem(row, 3, QTableWidgetItem(str(p.get("author", ""))))
|
|
@@ -141,15 +154,57 @@ class PluginManagerWindow(QDialog):
|
|
|
141
154
|
# Simple color coding for status
|
|
142
155
|
status = str(p.get("status", ""))
|
|
143
156
|
color = None
|
|
157
|
+
checkbox_color = None
|
|
144
158
|
if status.startswith("Error"):
|
|
145
159
|
color = Qt.GlobalColor.red
|
|
160
|
+
checkbox_color = "red"
|
|
146
161
|
elif status == "Loaded":
|
|
147
162
|
color = Qt.GlobalColor.darkGreen
|
|
148
|
-
|
|
163
|
+
checkbox_color = "darkgreen"
|
|
164
|
+
elif status in ("No Entry Point", "Disabled"):
|
|
149
165
|
color = Qt.GlobalColor.gray
|
|
166
|
+
checkbox_color = "gray"
|
|
150
167
|
|
|
151
168
|
if color:
|
|
152
|
-
|
|
169
|
+
status_checkbox.setStyleSheet(
|
|
170
|
+
f"QCheckBox {{ padding-left: 4px; color: {checkbox_color}; }}"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
def _status_checkbox(self, row: int) -> Optional[QCheckBox]:
|
|
174
|
+
"""Return the visible status checkbox for a plugin table row."""
|
|
175
|
+
checkbox = self.table.cellWidget(row, 0)
|
|
176
|
+
return checkbox if isinstance(checkbox, QCheckBox) else None
|
|
177
|
+
|
|
178
|
+
def _save_checkbox_preferences(self) -> set[str]:
|
|
179
|
+
"""Collect and persist checkbox choices."""
|
|
180
|
+
disabled_paths = set()
|
|
181
|
+
for row, plugin in enumerate(self.plugin_manager.plugins):
|
|
182
|
+
status_checkbox = self._status_checkbox(row)
|
|
183
|
+
if status_checkbox is not None and not status_checkbox.isChecked():
|
|
184
|
+
filepath = plugin.get("filepath")
|
|
185
|
+
if filepath:
|
|
186
|
+
disabled_paths.add(self.plugin_manager.plugin_path_key(filepath))
|
|
187
|
+
|
|
188
|
+
self.plugin_manager.save_disabled_plugins(disabled_paths)
|
|
189
|
+
return disabled_paths
|
|
190
|
+
|
|
191
|
+
def _apply_plugin_preferences(self) -> None:
|
|
192
|
+
"""Persist checkbox choices and reload plugins."""
|
|
193
|
+
if self._preferences_applied:
|
|
194
|
+
return
|
|
195
|
+
self._preferences_applied = True
|
|
196
|
+
|
|
197
|
+
self._save_checkbox_preferences()
|
|
198
|
+
if self.plugin_manager.main_window:
|
|
199
|
+
self.plugin_manager.discover_plugins(self.plugin_manager.main_window)
|
|
200
|
+
self.plugin_manager.rebuild_plugin_menus()
|
|
201
|
+
else:
|
|
202
|
+
self.plugin_manager.discover_plugins()
|
|
203
|
+
|
|
204
|
+
def done(self, result: int) -> None:
|
|
205
|
+
"""Apply plugin preferences for every way the dialog can close."""
|
|
206
|
+
self._apply_plugin_preferences()
|
|
207
|
+
super().done(result)
|
|
153
208
|
|
|
154
209
|
def update_button_state(self) -> None:
|
|
155
210
|
"""Enable or disable the Remove button based on table selection."""
|
|
@@ -159,6 +214,7 @@ class PluginManagerWindow(QDialog):
|
|
|
159
214
|
|
|
160
215
|
def on_reload(self, silent: bool = False) -> None:
|
|
161
216
|
"""Reload all plugins from disk, rebuild main-window UI, and refresh the table."""
|
|
217
|
+
self._save_checkbox_preferences()
|
|
162
218
|
if self.plugin_manager.main_window:
|
|
163
219
|
self.plugin_manager.discover_plugins(self.plugin_manager.main_window)
|
|
164
220
|
self.plugin_manager.rebuild_plugin_menus()
|
|
@@ -1663,7 +1663,6 @@ class MainInitManager:
|
|
|
1663
1663
|
|
|
1664
1664
|
dlg = PluginManagerWindow(self.host.plugin_manager, self.host)
|
|
1665
1665
|
dlg.exec()
|
|
1666
|
-
self.plugin_menu_manager.update_plugin_menu(self.plugin_menu)
|
|
1667
1666
|
|
|
1668
1667
|
manage_plugins_action.triggered.connect(show_plugin_manager)
|
|
1669
1668
|
self.plugin_menu.addAction(manage_plugins_action)
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/plugin_menu_manager.py
RENAMED
|
@@ -428,7 +428,6 @@ class PluginMenuManager:
|
|
|
428
428
|
|
|
429
429
|
dlg = PluginManagerWindow(self._im.host.plugin_manager, self._im.host)
|
|
430
430
|
dlg.exec()
|
|
431
|
-
self.update_plugin_menu(plugin_menu)
|
|
432
431
|
|
|
433
432
|
def _clear_all_plugin_actions(self) -> None:
|
|
434
433
|
"""Remove all tagged plugin actions from every menu and the export button.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/MoleditPy_linux.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/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-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/plugins/plugin_interface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/align_plane_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/base_picking_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/bond_length_dialog.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/calculation_worker.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/color_settings_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/custom_interactor_style.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/custom_qt_interactor.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/edit_actions_logic.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/geometry_base_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/molecular_scene_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/move_group_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/periodic_table_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/settings_tabs/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/template_preview_item.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/template_preview_view.py
RENAMED
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/translation_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/ui/user_template_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/default_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
{moleditpy_linux-4.9.3 → moleditpy_linux-4.10.1}/src/moleditpy_linux/utils/sip_isdeleted_safe.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|