MoleditPy-linux 2.4.1__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 (59) hide show
  1. moleditpy_linux/__init__.py +17 -0
  2. moleditpy_linux/__main__.py +29 -0
  3. moleditpy_linux/main.py +37 -0
  4. moleditpy_linux/modules/__init__.py +41 -0
  5. moleditpy_linux/modules/about_dialog.py +104 -0
  6. moleditpy_linux/modules/align_plane_dialog.py +292 -0
  7. moleditpy_linux/modules/alignment_dialog.py +272 -0
  8. moleditpy_linux/modules/analysis_window.py +209 -0
  9. moleditpy_linux/modules/angle_dialog.py +440 -0
  10. moleditpy_linux/modules/assets/file_icon.ico +0 -0
  11. moleditpy_linux/modules/assets/icon.icns +0 -0
  12. moleditpy_linux/modules/assets/icon.ico +0 -0
  13. moleditpy_linux/modules/assets/icon.png +0 -0
  14. moleditpy_linux/modules/atom_item.py +395 -0
  15. moleditpy_linux/modules/bond_item.py +464 -0
  16. moleditpy_linux/modules/bond_length_dialog.py +380 -0
  17. moleditpy_linux/modules/calculation_worker.py +766 -0
  18. moleditpy_linux/modules/color_settings_dialog.py +321 -0
  19. moleditpy_linux/modules/constants.py +88 -0
  20. moleditpy_linux/modules/constrained_optimization_dialog.py +678 -0
  21. moleditpy_linux/modules/custom_interactor_style.py +749 -0
  22. moleditpy_linux/modules/custom_qt_interactor.py +102 -0
  23. moleditpy_linux/modules/dialog3_d_picking_mixin.py +141 -0
  24. moleditpy_linux/modules/dihedral_dialog.py +443 -0
  25. moleditpy_linux/modules/main_window.py +850 -0
  26. moleditpy_linux/modules/main_window_app_state.py +787 -0
  27. moleditpy_linux/modules/main_window_compute.py +1242 -0
  28. moleditpy_linux/modules/main_window_dialog_manager.py +460 -0
  29. moleditpy_linux/modules/main_window_edit_3d.py +536 -0
  30. moleditpy_linux/modules/main_window_edit_actions.py +1565 -0
  31. moleditpy_linux/modules/main_window_export.py +917 -0
  32. moleditpy_linux/modules/main_window_main_init.py +2100 -0
  33. moleditpy_linux/modules/main_window_molecular_parsers.py +1044 -0
  34. moleditpy_linux/modules/main_window_project_io.py +434 -0
  35. moleditpy_linux/modules/main_window_string_importers.py +275 -0
  36. moleditpy_linux/modules/main_window_ui_manager.py +602 -0
  37. moleditpy_linux/modules/main_window_view_3d.py +1539 -0
  38. moleditpy_linux/modules/main_window_view_loaders.py +355 -0
  39. moleditpy_linux/modules/mirror_dialog.py +122 -0
  40. moleditpy_linux/modules/molecular_data.py +302 -0
  41. moleditpy_linux/modules/molecule_scene.py +2000 -0
  42. moleditpy_linux/modules/move_group_dialog.py +600 -0
  43. moleditpy_linux/modules/periodic_table_dialog.py +84 -0
  44. moleditpy_linux/modules/planarize_dialog.py +220 -0
  45. moleditpy_linux/modules/plugin_interface.py +215 -0
  46. moleditpy_linux/modules/plugin_manager.py +473 -0
  47. moleditpy_linux/modules/plugin_manager_window.py +274 -0
  48. moleditpy_linux/modules/settings_dialog.py +1503 -0
  49. moleditpy_linux/modules/template_preview_item.py +157 -0
  50. moleditpy_linux/modules/template_preview_view.py +74 -0
  51. moleditpy_linux/modules/translation_dialog.py +364 -0
  52. moleditpy_linux/modules/user_template_dialog.py +692 -0
  53. moleditpy_linux/modules/zoomable_view.py +129 -0
  54. moleditpy_linux-2.4.1.dist-info/METADATA +954 -0
  55. moleditpy_linux-2.4.1.dist-info/RECORD +59 -0
  56. moleditpy_linux-2.4.1.dist-info/WHEEL +5 -0
  57. moleditpy_linux-2.4.1.dist-info/entry_points.txt +2 -0
  58. moleditpy_linux-2.4.1.dist-info/licenses/LICENSE +674 -0
  59. moleditpy_linux-2.4.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,850 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ MoleditPy — A Python-based molecular editing software
6
+
7
+ Author: Hiromichi Yokoyama
8
+ License: GPL-3.0 license
9
+ Repo: https://github.com/HiroYokoyama/python_molecular_editor
10
+ DOI: 10.5281/zenodo.17268532
11
+ """
12
+
13
+ import traceback
14
+
15
+
16
+ # RDKit imports (explicit to satisfy flake8 and used features)
17
+ try:
18
+ pass
19
+ except Exception:
20
+ pass
21
+
22
+ # PyQt6 Modules
23
+ from PyQt6.QtWidgets import (
24
+ QMainWindow
25
+ )
26
+
27
+
28
+
29
+ from PyQt6.QtCore import (
30
+ pyqtSignal, pyqtSlot
31
+ )
32
+
33
+
34
+ # Use centralized Open Babel availability from package-level __init__
35
+ # Use per-package modules availability (local __init__).
36
+ try:
37
+ from . import OBABEL_AVAILABLE
38
+ except Exception:
39
+ from modules import OBABEL_AVAILABLE
40
+ # Only import pybel on demand — `moleditpy` itself doesn't expose `pybel`.
41
+ if OBABEL_AVAILABLE:
42
+ try:
43
+ from openbabel import pybel
44
+ except Exception:
45
+ # If import fails here, disable OBABEL locally; avoid raising
46
+ pybel = None
47
+ OBABEL_AVAILABLE = False
48
+ print("Warning: openbabel.pybel not available. Open Babel fallback and OBabel-based options will be disabled.")
49
+ else:
50
+ pybel = None
51
+
52
+ # Optional SIP helper: on some PyQt6 builds sip.isdeleted is available and
53
+ # allows safely detecting C++ wrapper objects that have been deleted. Import
54
+ # it once at module import time and expose a small, robust wrapper so callers
55
+ # can avoid re-importing sip repeatedly and so we centralize exception
56
+ # handling (this reduces crash risk during teardown and deletion operations).
57
+ try:
58
+ import sip as _sip # type: ignore
59
+ _sip_isdeleted = getattr(_sip, 'isdeleted', None)
60
+ except Exception:
61
+ _sip = None
62
+ _sip_isdeleted = None
63
+
64
+ try:
65
+ # package relative imports (preferred when running as `python -m moleditpy`)
66
+ from .main_window_app_state import MainWindowAppState
67
+ from .main_window_compute import MainWindowCompute
68
+ from .main_window_dialog_manager import MainWindowDialogManager
69
+ from .main_window_edit_3d import MainWindowEdit3d
70
+ from .main_window_edit_actions import MainWindowEditActions
71
+ from .main_window_export import MainWindowExport
72
+ from .main_window_main_init import MainWindowMainInit
73
+ from .main_window_molecular_parsers import MainWindowMolecularParsers
74
+ from .main_window_project_io import MainWindowProjectIo
75
+ from .main_window_string_importers import MainWindowStringImporters
76
+ from .main_window_ui_manager import MainWindowUiManager
77
+ from .main_window_view_3d import MainWindowView3d
78
+ from .main_window_view_loaders import MainWindowViewLoaders
79
+ except Exception:
80
+ # Fallback to absolute imports for script-style execution
81
+ from modules.main_window_app_state import MainWindowAppState
82
+ from modules.main_window_compute import MainWindowCompute
83
+ from modules.main_window_dialog_manager import MainWindowDialogManager
84
+ from modules.main_window_edit_3d import MainWindowEdit3d
85
+ from modules.main_window_edit_actions import MainWindowEditActions
86
+ from modules.main_window_export import MainWindowExport
87
+ from modules.main_window_main_init import MainWindowMainInit
88
+ from modules.main_window_molecular_parsers import MainWindowMolecularParsers
89
+ from modules.main_window_project_io import MainWindowProjectIo
90
+ from modules.main_window_string_importers import MainWindowStringImporters
91
+ from modules.main_window_ui_manager import MainWindowUiManager
92
+ from modules.main_window_view_3d import MainWindowView3d
93
+ from modules.main_window_view_loaders import MainWindowViewLoaders
94
+
95
+ class MainWindow(QMainWindow):
96
+
97
+ # start_calculation carries the MOL block and an options object (second arg)
98
+ start_calculation = pyqtSignal(str, object)
99
+ def __init__(self, initial_file=None):
100
+ # Initialize QMainWindow to ensure underlying Qt object is prepared
101
+ # before helper classes interact with the window (fixes crash when
102
+ # QMainWindow.__init__ not called).
103
+ super().__init__()
104
+ # --- MOVED TO main_window_main_init.py ---
105
+ # The window functionality has been split across several helper
106
+ # modules (main_window_*). Each helper is implemented as a class
107
+ # whose methods were originally written to operate on the
108
+ # MainWindow instance as 'self'. To maintain that behaviour we
109
+ # create a small proxy (BoundFeature) that will forward call to
110
+ # the helper class with the MainWindow instance as the first
111
+ # argument.
112
+ # Undo/Redo操作中に状態復元中であることを示すフラグ
113
+ # 他のモジュールが呼び出される前に初期化する
114
+ self._is_restoring_state = False
115
+
116
+ class BoundFeature:
117
+ """Bind a feature-class method calls to the MainWindow.
118
+
119
+ Usage:
120
+ self.main_window_view_3d = BoundFeature(MainWindowView3d, self)
121
+ self.main_window_view_3d.set_3d_style('cpk') # calls
122
+ MainWindowView3d.set_3d_style(self, 'cpk')
123
+ """
124
+
125
+ def __init__(self, cls, host):
126
+ self._cls = cls
127
+ self._host = host
128
+
129
+ def __getattr__(self, name):
130
+ # Return a function which calls the class method with the
131
+ # host (MainWindow instance) bound as first argument.
132
+ attr = getattr(self._cls, name)
133
+ if callable(attr):
134
+ return lambda *a, **k: attr(self._host, *a, **k)
135
+ return attr
136
+
137
+ def init(self, *a, **k):
138
+ """Explicit initializer delegator for helper classes.
139
+
140
+ Some helper classes define an __init__ method; when calling
141
+ it via the BoundFeature instance, Python would resolve to the
142
+ BoundFeature.__init__ method instead of the helper's.
143
+ This helper method allows callers to forward initialization
144
+ to the helper class implementation without touching _cls.
145
+ """
146
+ init_method = getattr(self._cls, '__init__', None)
147
+ if callable(init_method):
148
+ return init_method(self._host, *a, **k)
149
+ return None
150
+
151
+ # Attach bound helpers to the main window; this keeps the
152
+ # original call sites (e.g. self.main_window_compute.trigger_conversion)
153
+ # working without changing them.
154
+ self.main_window_main_init = BoundFeature(MainWindowMainInit, self)
155
+ self.main_window_ui_manager = BoundFeature(MainWindowUiManager, self)
156
+ self.main_window_view_3d = BoundFeature(MainWindowView3d, self)
157
+ self.main_window_compute = BoundFeature(MainWindowCompute, self)
158
+ self.main_window_edit_actions = BoundFeature(MainWindowEditActions, self)
159
+ self.main_window_string_importers = BoundFeature(MainWindowStringImporters, self)
160
+ self.main_window_molecular_parsers = BoundFeature(MainWindowMolecularParsers, self)
161
+ self.main_window_view_loaders = BoundFeature(MainWindowViewLoaders, self)
162
+ self.main_window_project_io = BoundFeature(MainWindowProjectIo, self)
163
+ self.main_window_app_state = BoundFeature(MainWindowAppState, self)
164
+ self.main_window_export = BoundFeature(MainWindowExport, self)
165
+ self.main_window_dialog_manager = BoundFeature(MainWindowDialogManager, self)
166
+ self.main_window_edit_3d = BoundFeature(MainWindowEdit3d, self)
167
+
168
+ # Call the initialization method from main_window_main_init which
169
+ # sets up the UI and the initial app state. Other helpers may
170
+ # expect the UI to exist so initialize them after this call.
171
+ try:
172
+ # The helper's __init__ usually accepts the initial_file
173
+ # argument and is expected to be invoked with the MainWindow
174
+ # instance as the host. Because BoundFeature itself defines
175
+ # __init__, attribute lookup would resolve to BoundFeature.__init__
176
+ # instead of the helper class method. Call the helper class
177
+ # __init__ explicitly with the main window instance as the
178
+ # first argument.
179
+ # Call the helper's __init__ via helper proxy to ensure the
180
+ # initial host and arguments are forwarded correctly.
181
+ self.main_window_main_init.init(initial_file)
182
+ except Exception:
183
+ # If main init fails, still continue so we can attempt
184
+ # to catch / repair other issues via error messages.
185
+ traceback.print_exc()
186
+
187
+ # Initialize other helper modules which implement their own
188
+ # __init__(self, main_window) if present.
189
+ other_inits = [
190
+ 'main_window_view_3d', 'main_window_ui_manager', 'main_window_compute',
191
+ 'main_window_edit_actions', 'main_window_string_importers',
192
+ 'main_window_molecular_parsers', 'main_window_view_loaders',
193
+ 'main_window_project_io', 'main_window_app_state', 'main_window_export',
194
+ 'main_window_dialog_manager', 'main_window_edit_3d'
195
+ ]
196
+ for name in other_inits:
197
+ try:
198
+ # Call the helper's __init__ through the proxy helper to
199
+ # avoid attribute-resolution issues.
200
+ getattr(self, name).init()
201
+ except Exception:
202
+ # Ignore; many helpers only define __init__ when they
203
+ # actually need it.
204
+ pass
205
+
206
+ def init_ui(self):
207
+ # --- MOVED TO main_window_main_init.py ---
208
+ return self.main_window_main_init.init_ui()
209
+
210
+ def init_menu_bar(self):
211
+ # --- MOVED TO main_window_main_init.py ---
212
+ return self.main_window_main_init.init_menu_bar()
213
+
214
+ def update_plugin_menu(self, plugin_menu):
215
+ # --- MOVED TO main_window_main_init.py ---
216
+ return self.main_window_main_init.update_plugin_menu(plugin_menu)
217
+
218
+ def init_worker_thread(self):
219
+ # --- MOVED TO main_window_main_init.py ---
220
+ return self.main_window_main_init.init_worker_thread()
221
+
222
+ def update_status_bar(self, message):
223
+ # --- MOVED TO main_window_ui_manager.py ---
224
+ return self.main_window_ui_manager.update_status_bar(message)
225
+
226
+ def set_mode(self, mode_str):
227
+ # --- MOVED TO main_window_ui_manager.py ---
228
+ return self.main_window_ui_manager.set_mode(mode_str)
229
+
230
+ def set_mode_and_update_toolbar(self, mode_str):
231
+ # --- MOVED TO main_window_ui_manager.py ---
232
+ return self.main_window_ui_manager.set_mode_and_update_toolbar(mode_str)
233
+
234
+ def set_3d_style(self, style_name):
235
+ # --- MOVED TO main_window_view_3d.py ---
236
+ return self.main_window_view_3d.set_3d_style(style_name)
237
+
238
+ def set_optimization_method(self, method_name):
239
+ # --- MOVED TO main_window_compute.py ---
240
+ return self.main_window_compute.set_optimization_method(method_name)
241
+
242
+ def copy_selection(self):
243
+ # --- MOVED TO main_window_edit_actions.py ---
244
+ return self.main_window_edit_actions.copy_selection()
245
+
246
+ def cut_selection(self):
247
+ # --- MOVED TO main_window_edit_actions.py ---
248
+ return self.main_window_edit_actions.cut_selection()
249
+
250
+ def paste_from_clipboard(self):
251
+ # --- MOVED TO main_window_edit_actions.py ---
252
+ return self.main_window_edit_actions.paste_from_clipboard()
253
+
254
+ def remove_hydrogen_atoms(self):
255
+ # --- MOVED TO main_window_edit_actions.py ---
256
+ return self.main_window_edit_actions.remove_hydrogen_atoms()
257
+
258
+ def add_hydrogen_atoms(self):
259
+ # --- MOVED TO main_window_edit_actions.py ---
260
+ return self.main_window_edit_actions.add_hydrogen_atoms()
261
+
262
+ def update_edit_menu_actions(self):
263
+ # --- MOVED TO main_window_edit_actions.py ---
264
+ return self.main_window_edit_actions.update_edit_menu_actions()
265
+
266
+ def show_convert_menu(self, pos):
267
+ # --- MOVED TO main_window_compute.py ---
268
+ return self.main_window_compute.show_convert_menu(pos)
269
+
270
+ def activate_select_mode(self):
271
+ # --- MOVED TO main_window_ui_manager.py ---
272
+ return self.main_window_ui_manager.activate_select_mode()
273
+
274
+ def _trigger_conversion_with_temp_mode(self, mode_key):
275
+ # --- MOVED TO main_window_compute.py ---
276
+ return self.main_window_compute._trigger_conversion_with_temp_mode(mode_key)
277
+
278
+ def show_optimize_menu(self, pos):
279
+ # --- MOVED TO main_window_compute.py ---
280
+ return self.main_window_compute.show_optimize_menu(pos)
281
+
282
+ def _trigger_optimize_with_temp_method(self, method_key):
283
+ # --- MOVED TO main_window_compute.py ---
284
+ return self.main_window_compute._trigger_optimize_with_temp_method(method_key)
285
+
286
+ def trigger_conversion(self):
287
+ # --- MOVED TO main_window_compute.py ---
288
+ return self.main_window_compute.trigger_conversion()
289
+
290
+ def halt_conversion(self):
291
+ # --- MOVED TO main_window_compute.py ---
292
+ return self.main_window_compute.halt_conversion()
293
+
294
+ def check_chemistry_problems_fallback(self):
295
+ # --- MOVED TO main_window_compute.py ---
296
+ return self.main_window_compute.check_chemistry_problems_fallback()
297
+
298
+ def optimize_3d_structure(self):
299
+ # --- MOVED TO main_window_compute.py ---
300
+ return self.main_window_compute.optimize_3d_structure()
301
+
302
+ def on_calculation_finished(self, result):
303
+ # --- MOVED TO main_window_compute.py ---
304
+ return self.main_window_compute.on_calculation_finished(result)
305
+
306
+ def create_atom_id_mapping(self):
307
+ # --- MOVED TO main_window_compute.py ---
308
+ return self.main_window_compute.create_atom_id_mapping()
309
+
310
+ @pyqtSlot(object)
311
+ def on_calculation_error(self, result):
312
+ # --- MOVED TO main_window_compute.py ---
313
+ return self.main_window_compute.on_calculation_error(result)
314
+
315
+ def eventFilter(self, obj, event):
316
+ # --- MOVED TO main_window_ui_manager.py ---
317
+ return self.main_window_ui_manager.eventFilter(obj, event)
318
+
319
+ def get_current_state(self):
320
+ # --- MOVED TO main_window_app_state.py ---
321
+ return self.main_window_app_state.get_current_state()
322
+
323
+ def set_state_from_data(self, state_data):
324
+ # --- MOVED TO main_window_app_state.py ---
325
+ return self.main_window_app_state.set_state_from_data(state_data)
326
+
327
+ def push_undo_state(self):
328
+ # --- MOVED TO main_window_app_state.py ---
329
+ return self.main_window_app_state.push_undo_state()
330
+
331
+ def update_window_title(self):
332
+ # --- MOVED TO main_window_app_state.py ---
333
+ return self.main_window_app_state.update_window_title()
334
+
335
+ def check_unsaved_changes(self):
336
+ # --- MOVED TO main_window_app_state.py ---
337
+ return self.main_window_app_state.check_unsaved_changes()
338
+
339
+ def reset_undo_stack(self):
340
+ # --- MOVED TO main_window_app_state.py ---
341
+ return self.main_window_app_state.reset_undo_stack()
342
+
343
+ def undo(self):
344
+ # --- MOVED TO main_window_app_state.py ---
345
+ return self.main_window_app_state.undo()
346
+
347
+ def redo(self):
348
+ # --- MOVED TO main_window_app_state.py ---
349
+ return self.main_window_app_state.redo()
350
+
351
+ def update_undo_redo_actions(self):
352
+ # --- MOVED TO main_window_app_state.py ---
353
+ return self.main_window_app_state.update_undo_redo_actions()
354
+
355
+ def update_realtime_info(self):
356
+ # --- MOVED TO main_window_app_state.py ---
357
+ return self.main_window_app_state.update_realtime_info()
358
+
359
+ def select_all(self):
360
+ # --- MOVED TO main_window_edit_actions.py ---
361
+ return self.main_window_edit_actions.select_all()
362
+
363
+ def show_about_dialog(self):
364
+ # --- MOVED TO main_window_dialog_manager.py ---
365
+ return self.main_window_dialog_manager.show_about_dialog()
366
+
367
+ def clear_all(self):
368
+ # --- MOVED TO main_window_edit_actions.py ---
369
+ return self.main_window_edit_actions.clear_all()
370
+
371
+ def clear_2d_editor(self, push_to_undo=True):
372
+ # --- MOVED TO main_window_edit_actions.py ---
373
+ return self.main_window_edit_actions.clear_2d_editor(push_to_undo=True)
374
+
375
+ def update_implicit_hydrogens(self):
376
+ # --- MOVED TO main_window_edit_actions.py ---
377
+ return self.main_window_edit_actions.update_implicit_hydrogens()
378
+
379
+ def import_smiles_dialog(self):
380
+ # --- MOVED TO main_window_string_importers.py ---
381
+ return self.main_window_string_importers.import_smiles_dialog()
382
+
383
+ def import_inchi_dialog(self):
384
+ # --- MOVED TO main_window_string_importers.py ---
385
+ return self.main_window_string_importers.import_inchi_dialog()
386
+
387
+ def load_from_smiles(self, smiles_string):
388
+ # --- MOVED TO main_window_string_importers.py ---
389
+ return self.main_window_string_importers.load_from_smiles(smiles_string)
390
+
391
+ def load_from_inchi(self, inchi_string):
392
+ # --- MOVED TO main_window_string_importers.py ---
393
+ return self.main_window_string_importers.load_from_inchi(inchi_string)
394
+
395
+ def fix_mol_counts_line(self, line: str) -> str:
396
+ # --- MOVED TO main_window_molecular_parsers.py ---
397
+ return self.main_window_molecular_parsers.fix_mol_counts_line(line)
398
+
399
+ def fix_mol_block(self, mol_block: str) -> str:
400
+ # --- MOVED TO main_window_molecular_parsers.py ---
401
+ return self.main_window_molecular_parsers.fix_mol_block(mol_block)
402
+
403
+ def load_mol_file(self, file_path=None):
404
+ # --- MOVED TO main_window_molecular_parsers.py ---
405
+ return self.main_window_molecular_parsers.load_mol_file(file_path)
406
+
407
+ def load_mol_for_3d_viewing(self):
408
+ # --- MOVED TO main_window_view_loaders.py ---
409
+ return self.main_window_view_loaders.load_mol_for_3d_viewing()
410
+
411
+ def load_xyz_for_3d_viewing(self, file_path=None):
412
+ # --- MOVED TO main_window_view_loaders.py ---
413
+ return self.main_window_view_loaders.load_xyz_for_3d_viewing(file_path)
414
+
415
+ def load_xyz_file(self, file_path=None):
416
+ # --- MOVED TO main_window_molecular_parsers.py ---
417
+ return self.main_window_molecular_parsers.load_xyz_file(file_path)
418
+
419
+ def estimate_bonds_from_distances(self, mol):
420
+ # --- MOVED TO main_window_molecular_parsers.py ---
421
+ return self.main_window_molecular_parsers.estimate_bonds_from_distances(mol)
422
+
423
+ def save_project(self):
424
+ # --- MOVED TO main_window_project_io.py ---
425
+ return self.main_window_project_io.save_project()
426
+
427
+ def save_project_as(self):
428
+ # --- MOVED TO main_window_project_io.py ---
429
+ return self.main_window_project_io.save_project_as()
430
+
431
+ def save_raw_data(self):
432
+ # --- MOVED TO main_window_project_io.py ---
433
+ return self.main_window_project_io.save_raw_data()
434
+
435
+ def load_raw_data(self, file_path=None):
436
+ # --- MOVED TO main_window_project_io.py ---
437
+ return self.main_window_project_io.load_raw_data(file_path)
438
+
439
+ def save_as_json(self):
440
+ # --- MOVED TO main_window_project_io.py ---
441
+ return self.main_window_project_io.save_as_json()
442
+
443
+ def create_json_data(self):
444
+ # --- MOVED TO main_window_app_state.py ---
445
+ return self.main_window_app_state.create_json_data()
446
+
447
+ def load_json_data(self, file_path=None):
448
+ # --- MOVED TO main_window_project_io.py ---
449
+ return self.main_window_project_io.load_json_data(file_path)
450
+
451
+ def open_project_file(self, file_path=None):
452
+ # --- MOVED TO main_window_project_io.py ---
453
+ return self.main_window_project_io.open_project_file(file_path)
454
+
455
+ def load_from_json_data(self, json_data):
456
+ # --- MOVED TO main_window_app_state.py ---
457
+ return self.main_window_app_state.load_from_json_data(json_data)
458
+
459
+ def save_as_mol(self):
460
+ # --- MOVED TO main_window_molecular_parsers.py ---
461
+ return self.main_window_molecular_parsers.save_as_mol()
462
+
463
+ def save_3d_as_mol(self):
464
+ # --- MOVED TO main_window_view_loaders.py ---
465
+ return self.main_window_view_loaders.save_3d_as_mol()
466
+
467
+ def save_as_xyz(self):
468
+ # --- MOVED TO main_window_molecular_parsers.py ---
469
+ return self.main_window_molecular_parsers.save_as_xyz()
470
+
471
+ def export_stl(self):
472
+ # --- MOVED TO main_window_export.py ---
473
+ return self.main_window_export.export_stl()
474
+
475
+ def export_obj_mtl(self):
476
+ # --- MOVED TO main_window_export.py ---
477
+ return self.main_window_export.export_obj_mtl()
478
+
479
+ def create_multi_material_obj(self, meshes_with_colors, obj_path, mtl_path):
480
+ # --- MOVED TO main_window_export.py ---
481
+ return self.main_window_export.create_multi_material_obj(meshes_with_colors, obj_path, mtl_path)
482
+
483
+ def export_color_stl(self):
484
+ # --- MOVED TO main_window_export.py ---
485
+ return self.main_window_export.export_color_stl()
486
+
487
+ def export_from_3d_view(self):
488
+ # --- MOVED TO main_window_export.py ---
489
+ return self.main_window_export.export_from_3d_view()
490
+
491
+ def export_from_3d_view_no_color(self):
492
+ # --- MOVED TO main_window_export.py ---
493
+ return self.main_window_export.export_from_3d_view_no_color()
494
+
495
+ def export_from_3d_view_with_colors(self):
496
+ # --- MOVED TO main_window_export.py ---
497
+ return self.main_window_export.export_from_3d_view_with_colors()
498
+
499
+ def export_2d_png(self):
500
+ # --- MOVED TO main_window_export.py ---
501
+ return self.main_window_export.export_2d_png()
502
+
503
+ def export_2d_svg(self):
504
+ # --- MOVED TO main_window_export.py ---
505
+ return self.main_window_export.export_2d_svg()
506
+
507
+ def export_3d_png(self):
508
+ # --- MOVED TO main_window_export.py ---
509
+ return self.main_window_export.export_3d_png()
510
+
511
+ def open_periodic_table_dialog(self):
512
+ # --- MOVED TO main_window_dialog_manager.py ---
513
+ return self.main_window_dialog_manager.open_periodic_table_dialog()
514
+
515
+ def set_atom_from_periodic_table(self, symbol):
516
+ self.set_mode(f'atom_{symbol}')
517
+
518
+
519
+ def clean_up_2d_structure(self):
520
+ # --- MOVED TO main_window_edit_actions.py ---
521
+ return self.main_window_edit_actions.clean_up_2d_structure()
522
+
523
+ def resolve_overlapping_groups(self):
524
+ # --- MOVED TO main_window_edit_actions.py ---
525
+ return self.main_window_edit_actions.resolve_overlapping_groups()
526
+
527
+ def adjust_molecule_positions_to_avoid_collisions(self, mol, frags):
528
+ # --- MOVED TO main_window_edit_actions.py ---
529
+ return self.main_window_edit_actions.adjust_molecule_positions_to_avoid_collisions(mol, frags)
530
+
531
+ def open_rotate_2d_dialog(self):
532
+ # --- MOVED TO main_window_edit_actions.py ---
533
+ return self.main_window_edit_actions.open_rotate_2d_dialog()
534
+
535
+ def draw_molecule_3d(self, mol):
536
+ # --- MOVED TO main_window_view_3d.py ---
537
+ return self.main_window_view_3d.draw_molecule_3d(mol)
538
+
539
+ def _calculate_double_bond_offset(self, mol, bond, conf):
540
+ # --- MOVED TO main_window_view_3d.py ---
541
+ return self.main_window_view_3d._calculate_double_bond_offset(mol, bond, conf)
542
+
543
+ def show_ez_labels_3d(self, mol):
544
+ # --- MOVED TO main_window_view_3d.py ---
545
+ return self.main_window_view_3d.show_ez_labels_3d(mol)
546
+
547
+ def toggle_chiral_labels_display(self, checked):
548
+ # --- MOVED TO main_window_view_3d.py ---
549
+ return self.main_window_view_3d.toggle_chiral_labels_display(checked)
550
+
551
+ def update_chiral_labels(self):
552
+ # --- MOVED TO main_window_view_3d.py ---
553
+ return self.main_window_view_3d.update_chiral_labels()
554
+
555
+ def toggle_atom_info_display(self, mode):
556
+ # --- MOVED TO main_window_view_3d.py ---
557
+ return self.main_window_view_3d.toggle_atom_info_display(mode)
558
+
559
+ def is_xyz_derived_molecule(self):
560
+ # --- MOVED TO main_window_view_3d.py ---
561
+ return self.main_window_view_3d.is_xyz_derived_molecule()
562
+
563
+ def has_original_atom_ids(self):
564
+ # --- MOVED TO main_window_view_3d.py ---
565
+ return self.main_window_view_3d.has_original_atom_ids()
566
+
567
+ def update_atom_id_menu_text(self):
568
+ # --- MOVED TO main_window_view_3d.py ---
569
+ return self.main_window_view_3d.update_atom_id_menu_text()
570
+
571
+ def update_atom_id_menu_state(self):
572
+ # --- MOVED TO main_window_view_3d.py ---
573
+ return self.main_window_view_3d.update_atom_id_menu_state()
574
+
575
+ def show_all_atom_info(self):
576
+ # --- MOVED TO main_window_view_3d.py ---
577
+ return self.main_window_view_3d.show_all_atom_info()
578
+
579
+ def clear_all_atom_info_labels(self):
580
+ # --- MOVED TO main_window_view_3d.py ---
581
+ return self.main_window_view_3d.clear_all_atom_info_labels()
582
+
583
+ def setup_3d_hover(self):
584
+ # --- MOVED TO main_window_view_3d.py ---
585
+ return self.main_window_view_3d.setup_3d_hover()
586
+
587
+ def open_analysis_window(self):
588
+ # --- MOVED TO main_window_dialog_manager.py ---
589
+ return self.main_window_dialog_manager.open_analysis_window()
590
+
591
+ def closeEvent(self, event):
592
+ # --- MOVED TO main_window_ui_manager.py ---
593
+ return self.main_window_ui_manager.closeEvent(event)
594
+
595
+ def zoom_in(self):
596
+ # --- MOVED TO main_window_view_3d.py ---
597
+ return self.main_window_view_3d.zoom_in()
598
+
599
+ def zoom_out(self):
600
+ # --- MOVED TO main_window_view_3d.py ---
601
+ return self.main_window_view_3d.zoom_out()
602
+
603
+ def reset_zoom(self):
604
+ # --- MOVED TO main_window_view_3d.py ---
605
+ return self.main_window_view_3d.reset_zoom()
606
+
607
+ def fit_to_view(self):
608
+ # --- MOVED TO main_window_view_3d.py ---
609
+ return self.main_window_view_3d.fit_to_view()
610
+
611
+ def draw_standard_3d_style(self, mol, style_override=None):
612
+ # --- MOVED TO main_window_view_3d.py ---
613
+ return self.main_window_view_3d.draw_standard_3d_style(mol, style_override)
614
+
615
+ def clear_measurement_selection(self):
616
+ # --- MOVED TO main_window_view_3d.py ---
617
+ return self.main_window_view_3d.clear_measurement_selection()
618
+
619
+ def toggle_3d_edit_mode(self, checked):
620
+ # --- MOVED TO main_window_ui_manager.py ---
621
+ return self.main_window_ui_manager.toggle_3d_edit_mode(checked)
622
+
623
+ def _setup_3d_picker(self):
624
+ # --- MOVED TO main_window_ui_manager.py ---
625
+ return self.main_window_ui_manager._setup_3d_picker()
626
+
627
+ def _apply_chem_check_and_set_flags(self, mol, source_desc=None):
628
+ # --- MOVED TO main_window_edit_actions.py ---
629
+ return self.main_window_edit_actions._apply_chem_check_and_set_flags(mol, source_desc=None)
630
+
631
+ def _clear_xyz_flags(self, mol=None):
632
+ # --- MOVED TO main_window_edit_actions.py ---
633
+ return self.main_window_edit_actions._clear_xyz_flags(mol=None)
634
+
635
+ def load_mol_file_for_3d_viewing(self, file_path=None):
636
+ # --- MOVED TO main_window_view_loaders.py ---
637
+ return self.main_window_view_loaders.load_mol_file_for_3d_viewing(file_path)
638
+
639
+ def load_command_line_file(self, file_path):
640
+ # --- MOVED TO main_window_main_init.py ---
641
+ return self.main_window_main_init.load_command_line_file(file_path)
642
+
643
+ def dragEnterEvent(self, event):
644
+ # --- MOVED TO main_window_ui_manager.py ---
645
+ return self.main_window_ui_manager.dragEnterEvent(event)
646
+
647
+ def dropEvent(self, event):
648
+ # --- MOVED TO main_window_ui_manager.py ---
649
+ return self.main_window_ui_manager.dropEvent(event)
650
+
651
+ def _enable_3d_edit_actions(self, enabled=True):
652
+ # --- MOVED TO main_window_ui_manager.py ---
653
+ return self.main_window_ui_manager._enable_3d_edit_actions(enabled=True)
654
+
655
+ def _enable_3d_features(self, enabled=True):
656
+ # --- MOVED TO main_window_ui_manager.py ---
657
+ return self.main_window_ui_manager._enable_3d_features(enabled=True)
658
+
659
+ def _enter_3d_viewer_ui_mode(self):
660
+ # --- MOVED TO main_window_ui_manager.py ---
661
+ return self.main_window_ui_manager._enter_3d_viewer_ui_mode()
662
+
663
+ def restore_ui_for_editing(self):
664
+ # --- MOVED TO main_window_ui_manager.py ---
665
+ return self.main_window_ui_manager.restore_ui_for_editing()
666
+
667
+ def minimize_2d_panel(self):
668
+ # --- MOVED TO main_window_ui_manager.py ---
669
+ return self.main_window_ui_manager.minimize_2d_panel()
670
+
671
+ def restore_2d_panel(self):
672
+ # --- MOVED TO main_window_ui_manager.py ---
673
+ return self.main_window_ui_manager.restore_2d_panel()
674
+
675
+ def set_panel_layout(self, left_percent, right_percent):
676
+ # --- MOVED TO main_window_ui_manager.py ---
677
+ return self.main_window_ui_manager.set_panel_layout(left_percent, right_percent)
678
+
679
+ def toggle_2d_panel(self):
680
+ # --- MOVED TO main_window_ui_manager.py ---
681
+ return self.main_window_ui_manager.toggle_2d_panel()
682
+
683
+ def on_splitter_moved(self, pos, index):
684
+ # --- MOVED TO main_window_ui_manager.py ---
685
+ return self.main_window_ui_manager.on_splitter_moved(pos, index)
686
+
687
+ def open_template_dialog(self):
688
+ # --- MOVED TO main_window_dialog_manager.py ---
689
+ return self.main_window_dialog_manager.open_template_dialog()
690
+
691
+ def open_template_dialog_and_activate(self):
692
+ # --- MOVED TO main_window_dialog_manager.py ---
693
+ return self.main_window_dialog_manager.open_template_dialog_and_activate()
694
+
695
+ def save_2d_as_template(self):
696
+ # --- MOVED TO main_window_dialog_manager.py ---
697
+ return self.main_window_dialog_manager.save_2d_as_template()
698
+
699
+ def setup_splitter_tooltip(self):
700
+ # --- MOVED TO main_window_ui_manager.py ---
701
+ return self.main_window_ui_manager.setup_splitter_tooltip()
702
+
703
+ def apply_initial_settings(self):
704
+ # --- MOVED TO main_window_main_init.py ---
705
+ return self.main_window_main_init.apply_initial_settings()
706
+
707
+ def update_cpk_colors_from_settings(self):
708
+ # --- MOVED TO main_window_view_3d.py ---
709
+ return self.main_window_view_3d.update_cpk_colors_from_settings()
710
+
711
+ def apply_3d_settings(self, redraw=True):
712
+ # --- MOVED TO main_window_view_3d.py ---
713
+ return self.main_window_view_3d.apply_3d_settings(redraw=True)
714
+
715
+ def open_settings_dialog(self):
716
+ # --- MOVED TO main_window_main_init.py ---
717
+ return self.main_window_main_init.open_settings_dialog()
718
+
719
+ def reset_all_settings_menu(self):
720
+ # --- MOVED TO main_window_main_init.py ---
721
+ return self.main_window_main_init.reset_all_settings_menu()
722
+
723
+ def load_settings(self):
724
+ # --- MOVED TO main_window_main_init.py ---
725
+ return self.main_window_main_init.load_settings()
726
+
727
+ def save_settings(self):
728
+ # --- MOVED TO main_window_main_init.py ---
729
+ return self.main_window_main_init.save_settings()
730
+
731
+ def toggle_measurement_mode(self, checked):
732
+ # --- MOVED TO main_window_edit_3d.py ---
733
+ return self.main_window_edit_3d.toggle_measurement_mode(checked)
734
+
735
+ def close_all_3d_edit_dialogs(self):
736
+ # --- MOVED TO main_window_edit_3d.py ---
737
+ return self.main_window_edit_3d.close_all_3d_edit_dialogs()
738
+
739
+ def handle_measurement_atom_selection(self, atom_idx):
740
+ # --- MOVED TO main_window_edit_3d.py ---
741
+ return self.main_window_edit_3d.handle_measurement_atom_selection(atom_idx)
742
+
743
+ def add_measurement_label(self, atom_idx, label_number):
744
+ # --- MOVED TO main_window_edit_3d.py ---
745
+ return self.main_window_edit_3d.add_measurement_label(atom_idx, label_number)
746
+
747
+ def update_measurement_labels_display(self):
748
+ # --- MOVED TO main_window_edit_3d.py ---
749
+ return self.main_window_edit_3d.update_measurement_labels_display()
750
+
751
+ def clear_measurement_selection(self):
752
+ # --- MOVED TO main_window_edit_3d.py ---
753
+ return self.main_window_edit_3d.clear_measurement_selection()
754
+
755
+ def update_2d_measurement_labels(self):
756
+ # --- MOVED TO main_window_edit_3d.py ---
757
+ return self.main_window_edit_3d.update_2d_measurement_labels()
758
+
759
+ def add_2d_measurement_label(self, atom_item, label_text):
760
+ # --- MOVED TO main_window_edit_3d.py ---
761
+ return self.main_window_edit_3d.add_2d_measurement_label(atom_item, label_text)
762
+
763
+ def clear_2d_measurement_labels(self):
764
+ # --- MOVED TO main_window_edit_3d.py ---
765
+ return self.main_window_edit_3d.clear_2d_measurement_labels()
766
+
767
+ def find_rdkit_atom_index(self, atom_item):
768
+ # --- MOVED TO main_window_edit_3d.py ---
769
+ return self.main_window_edit_3d.find_rdkit_atom_index(atom_item)
770
+
771
+ def calculate_and_display_measurements(self):
772
+ # --- MOVED TO main_window_edit_3d.py ---
773
+ return self.main_window_edit_3d.calculate_and_display_measurements()
774
+
775
+ def calculate_distance(self, atom1_idx, atom2_idx):
776
+ # --- MOVED TO main_window_edit_3d.py ---
777
+ return self.main_window_edit_3d.calculate_distance(atom1_idx, atom2_idx)
778
+
779
+ def calculate_angle(self, atom1_idx, atom2_idx, atom3_idx):
780
+ # --- MOVED TO main_window_edit_3d.py ---
781
+ return self.main_window_edit_3d.calculate_angle(atom1_idx, atom2_idx, atom3_idx)
782
+
783
+ def calculate_dihedral(self, atom1_idx, atom2_idx, atom3_idx, atom4_idx):
784
+ # --- MOVED TO main_window_edit_3d.py ---
785
+ return self.main_window_edit_3d.calculate_dihedral(atom1_idx, atom2_idx, atom3_idx, atom4_idx)
786
+
787
+ def display_measurement_text(self, measurement_lines):
788
+ # --- MOVED TO main_window_edit_3d.py ---
789
+ return self.main_window_edit_3d.display_measurement_text(measurement_lines)
790
+
791
+ def toggle_atom_selection_3d(self, atom_idx):
792
+ # --- MOVED TO main_window_edit_3d.py ---
793
+ return self.main_window_edit_3d.toggle_atom_selection_3d(atom_idx)
794
+
795
+ def clear_3d_selection(self):
796
+ # --- MOVED TO main_window_edit_3d.py ---
797
+ return self.main_window_edit_3d.clear_3d_selection()
798
+
799
+ def update_3d_selection_display(self):
800
+ # --- MOVED TO main_window_edit_3d.py ---
801
+ return self.main_window_edit_3d.update_3d_selection_display()
802
+
803
+ def planarize_selection(self, plane):
804
+ # --- MOVED TO main_window_edit_3d.py ---
805
+ return self.main_window_edit_3d.planarize_selection(plane)
806
+
807
+ def open_translation_dialog(self):
808
+ # --- MOVED TO main_window_dialog_manager.py ---
809
+ return self.main_window_dialog_manager.open_translation_dialog()
810
+
811
+ def open_move_group_dialog(self):
812
+ # --- MOVED TO main_window_dialog_manager.py ---
813
+ return self.main_window_dialog_manager.open_move_group_dialog()
814
+
815
+ def open_align_plane_dialog(self, plane):
816
+ # --- MOVED TO main_window_dialog_manager.py ---
817
+ return self.main_window_dialog_manager.open_align_plane_dialog(plane)
818
+
819
+ def open_planarize_dialog(self, plane=None):
820
+ # --- MOVED TO main_window_dialog_manager.py ---
821
+ return self.main_window_dialog_manager.open_planarize_dialog(plane=None)
822
+
823
+ def open_alignment_dialog(self, axis):
824
+ # --- MOVED TO main_window_dialog_manager.py ---
825
+ return self.main_window_dialog_manager.open_alignment_dialog(axis)
826
+
827
+ def open_bond_length_dialog(self):
828
+ # --- MOVED TO main_window_dialog_manager.py ---
829
+ return self.main_window_dialog_manager.open_bond_length_dialog()
830
+
831
+ def open_angle_dialog(self):
832
+ # --- MOVED TO main_window_dialog_manager.py ---
833
+ return self.main_window_dialog_manager.open_angle_dialog()
834
+
835
+ def open_dihedral_dialog(self):
836
+ # --- MOVED TO main_window_dialog_manager.py ---
837
+ return self.main_window_dialog_manager.open_dihedral_dialog()
838
+
839
+ def open_mirror_dialog(self):
840
+ # --- MOVED TO main_window_dialog_manager.py ---
841
+ return self.main_window_dialog_manager.open_mirror_dialog()
842
+
843
+ def open_constrained_optimization_dialog(self):
844
+ # --- MOVED TO main_window_dialog_manager.py ---
845
+ return self.main_window_dialog_manager.open_constrained_optimization_dialog()
846
+
847
+ def remove_dialog_from_list(self, dialog):
848
+ # --- MOVED TO main_window_edit_3d.py ---
849
+ return self.main_window_edit_3d.remove_dialog_from_list(dialog)
850
+