MoleditPy-linux 1.17.1__py3-none-any.whl → 1.18.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.
- moleditpy_linux/modules/align_plane_dialog.py +1 -1
- moleditpy_linux/modules/alignment_dialog.py +1 -1
- moleditpy_linux/modules/angle_dialog.py +2 -2
- moleditpy_linux/modules/bond_item.py +96 -5
- moleditpy_linux/modules/bond_length_dialog.py +2 -2
- moleditpy_linux/modules/constants.py +1 -1
- moleditpy_linux/modules/constrained_optimization_dialog.py +2 -2
- moleditpy_linux/modules/dihedral_dialog.py +1 -1
- moleditpy_linux/modules/main_window_app_state.py +1 -1
- moleditpy_linux/modules/main_window_compute.py +6 -0
- moleditpy_linux/modules/main_window_edit_3d.py +7 -7
- moleditpy_linux/modules/main_window_export.py +106 -49
- moleditpy_linux/modules/main_window_main_init.py +3 -3
- moleditpy_linux/modules/main_window_molecular_parsers.py +4 -3
- moleditpy_linux/modules/main_window_project_io.py +2 -2
- moleditpy_linux/modules/main_window_view_3d.py +359 -131
- moleditpy_linux/modules/main_window_view_loaders.py +1 -1
- moleditpy_linux/modules/molecule_scene.py +14 -15
- moleditpy_linux/modules/planarize_dialog.py +1 -1
- moleditpy_linux/modules/settings_dialog.py +86 -20
- moleditpy_linux/modules/user_template_dialog.py +9 -8
- {moleditpy_linux-1.17.1.dist-info → moleditpy_linux-1.18.1.dist-info}/METADATA +1 -2
- {moleditpy_linux-1.17.1.dist-info → moleditpy_linux-1.18.1.dist-info}/RECORD +27 -27
- {moleditpy_linux-1.17.1.dist-info → moleditpy_linux-1.18.1.dist-info}/WHEEL +0 -0
- {moleditpy_linux-1.17.1.dist-info → moleditpy_linux-1.18.1.dist-info}/entry_points.txt +0 -0
- {moleditpy_linux-1.17.1.dist-info → moleditpy_linux-1.18.1.dist-info}/licenses/LICENSE +0 -0
- {moleditpy_linux-1.17.1.dist-info → moleditpy_linux-1.18.1.dist-info}/top_level.txt +0 -0
|
@@ -317,7 +317,7 @@ class MainWindowViewLoaders(object):
|
|
|
317
317
|
# Keep mol as-is (may lack conformer); downstream code checks for conformers
|
|
318
318
|
else:
|
|
319
319
|
raise
|
|
320
|
-
except:
|
|
320
|
+
except Exception:
|
|
321
321
|
self.statusBar().showMessage("Failed to generate 3D coordinates")
|
|
322
322
|
return
|
|
323
323
|
|
|
@@ -11,6 +11,7 @@ DOI: 10.5281/zenodo.17268532
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
import traceback
|
|
14
|
+
import logging
|
|
14
15
|
|
|
15
16
|
from PyQt6.QtWidgets import (
|
|
16
17
|
QApplication, QGraphicsScene, QGraphicsItem,
|
|
@@ -203,9 +204,7 @@ class MoleculeScene(QGraphicsScene):
|
|
|
203
204
|
self.window.push_undo_state()
|
|
204
205
|
data_changed = False # ここでundo済みなので以降で積まない
|
|
205
206
|
except Exception as e:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
traceback.print_exc()
|
|
207
|
+
logging.error(f"Error clearing E/Z label: {e}", exc_info=True)
|
|
209
208
|
if hasattr(self.window, 'statusBar'):
|
|
210
209
|
self.window.statusBar().showMessage(f"Error clearing E/Z label: {e}", 5000)
|
|
211
210
|
# AtomItemは何もしない
|
|
@@ -387,9 +386,7 @@ class MoleculeScene(QGraphicsScene):
|
|
|
387
386
|
self.update_bond_stereo(b, new_stereo)
|
|
388
387
|
self.window.push_undo_state() # ここでUndo stackに積む
|
|
389
388
|
except Exception as e:
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
traceback.print_exc()
|
|
389
|
+
logging.error(f"Error in E/Z stereo toggle: {e}", exc_info=True)
|
|
393
390
|
if hasattr(self.window, 'statusBar'):
|
|
394
391
|
self.window.statusBar().showMessage(f"Error changing E/Z stereochemistry: {e}", 5000)
|
|
395
392
|
return # この後の処理は行わない
|
|
@@ -610,7 +607,7 @@ class MoleculeScene(QGraphicsScene):
|
|
|
610
607
|
def create_bond(self, start_atom, end_atom, bond_order=None, bond_stereo=None):
|
|
611
608
|
try:
|
|
612
609
|
if start_atom is None or end_atom is None:
|
|
613
|
-
|
|
610
|
+
logging.error("Error: Cannot create bond with None atoms")
|
|
614
611
|
return
|
|
615
612
|
|
|
616
613
|
exist_b = self.find_bond_between(start_atom, end_atom)
|
|
@@ -637,9 +634,7 @@ class MoleculeScene(QGraphicsScene):
|
|
|
637
634
|
end_atom.update_style()
|
|
638
635
|
|
|
639
636
|
except Exception as e:
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
traceback.print_exc()
|
|
637
|
+
logging.error(f"Error creating bond: {e}", exc_info=True)
|
|
643
638
|
|
|
644
639
|
def add_molecule_fragment(self, points, bonds_info, existing_items=None, symbol='C'):
|
|
645
640
|
"""
|
|
@@ -1668,9 +1663,9 @@ class MoleculeScene(QGraphicsScene):
|
|
|
1668
1663
|
elif key == Qt.Key.Key_1 and (bond.order != 1 or bond.stereo != 0):
|
|
1669
1664
|
bond.order = 1; bond.stereo = 0
|
|
1670
1665
|
elif key == Qt.Key.Key_2 and (bond.order != 2 or bond.stereo != 0):
|
|
1671
|
-
bond.order = 2; bond.stereo = 0
|
|
1666
|
+
bond.order = 2; bond.stereo = 0
|
|
1672
1667
|
elif key == Qt.Key.Key_3 and bond.order != 3:
|
|
1673
|
-
bond.order = 3; bond.stereo = 0
|
|
1668
|
+
bond.order = 3; bond.stereo = 0
|
|
1674
1669
|
|
|
1675
1670
|
# 4. 実際に変更があった場合のみデータモデルを更新
|
|
1676
1671
|
if old_order != bond.order or old_stereo != bond.stereo:
|
|
@@ -1712,7 +1707,11 @@ class MoleculeScene(QGraphicsScene):
|
|
|
1712
1707
|
return
|
|
1713
1708
|
|
|
1714
1709
|
# --- 3. Atomに対する操作 (原子の追加 - マージされた機能) ---
|
|
1715
|
-
if key
|
|
1710
|
+
if key in [Qt.Key.Key_1, Qt.Key.Key_2, Qt.Key.Key_3]:
|
|
1711
|
+
target_order = 1
|
|
1712
|
+
if key == Qt.Key.Key_2: target_order = 2
|
|
1713
|
+
elif key == Qt.Key.Key_3: target_order = 3
|
|
1714
|
+
|
|
1716
1715
|
start_atom = None
|
|
1717
1716
|
if isinstance(item_at_cursor, AtomItem):
|
|
1718
1717
|
start_atom = item_at_cursor
|
|
@@ -1802,12 +1801,12 @@ class MoleculeScene(QGraphicsScene):
|
|
|
1802
1801
|
|
|
1803
1802
|
if near_atom and near_atom is not start_atom:
|
|
1804
1803
|
# 近くに既存原子があれば結合
|
|
1805
|
-
self.create_bond(start_atom, near_atom)
|
|
1804
|
+
self.create_bond(start_atom, near_atom, bond_order=target_order, bond_stereo=0)
|
|
1806
1805
|
else:
|
|
1807
1806
|
# 新規原子を作成し結合
|
|
1808
1807
|
new_atom_id = self.create_atom('C', target_pos)
|
|
1809
1808
|
new_atom_item = self.data.atoms[new_atom_id]['item']
|
|
1810
|
-
self.create_bond(start_atom, new_atom_item)
|
|
1809
|
+
self.create_bond(start_atom, new_atom_item, bond_order=target_order, bond_stereo=0)
|
|
1811
1810
|
|
|
1812
1811
|
self.clearSelection()
|
|
1813
1812
|
self.window.push_undo_state()
|
|
@@ -53,7 +53,6 @@ class SettingsDialog(QDialog):
|
|
|
53
53
|
'wireframe_bond_radius': 0.01,
|
|
54
54
|
'wireframe_resolution': 6,
|
|
55
55
|
# Stick model parameters
|
|
56
|
-
'stick_atom_radius': 0.15,
|
|
57
56
|
'stick_bond_radius': 0.15,
|
|
58
57
|
'stick_resolution': 16,
|
|
59
58
|
# Multiple bond offset parameters (per-model)
|
|
@@ -69,6 +68,9 @@ class SettingsDialog(QDialog):
|
|
|
69
68
|
'stick_triple_bond_offset_factor': 1.0,
|
|
70
69
|
'stick_double_bond_radius_factor': 0.6,
|
|
71
70
|
'stick_triple_bond_radius_factor': 0.4,
|
|
71
|
+
'aromatic_torus_thickness_factor': 0.6,
|
|
72
|
+
# Whether to draw an aromatic circle inside rings in 3D
|
|
73
|
+
'display_aromatic_circles_3d': False,
|
|
72
74
|
# If True, attempts to be permissive when RDKit raises chemical/sanitization errors
|
|
73
75
|
# during file import (useful for viewing malformed XYZ/MOL files). When enabled,
|
|
74
76
|
# element symbol recognition will be coerced where possible and Chem.SanitizeMol
|
|
@@ -86,6 +88,7 @@ class SettingsDialog(QDialog):
|
|
|
86
88
|
# If True, RDKit will attempt to kekulize aromatic systems for 3D display
|
|
87
89
|
# (shows alternating single/double bonds rather than aromatic circles)
|
|
88
90
|
'display_kekule_3d': False,
|
|
91
|
+
'ball_stick_use_cpk_bond_color': False,
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
# --- 選択された色を管理する専用のインスタンス変数 ---
|
|
@@ -118,6 +121,13 @@ class SettingsDialog(QDialog):
|
|
|
118
121
|
|
|
119
122
|
# 渡された設定でUIと内部変数を初期化
|
|
120
123
|
self.update_ui_from_settings(current_settings)
|
|
124
|
+
|
|
125
|
+
# Initialize aromatic circle checkbox and torus thickness from settings
|
|
126
|
+
self.aromatic_circle_checkbox.setChecked(current_settings.get('display_aromatic_circles_3d', self.default_settings.get('display_aromatic_circles_3d', False)))
|
|
127
|
+
# Thickness factor is stored as a multiplier (e.g., 1.0), slider uses integer 0-300 representing 0.1x-3.0x
|
|
128
|
+
thickness_factor = current_settings.get('aromatic_torus_thickness_factor', self.default_settings.get('aromatic_torus_thickness_factor', 1.0))
|
|
129
|
+
self.aromatic_torus_thickness_slider.setValue(int(thickness_factor * 100))
|
|
130
|
+
self.aromatic_torus_thickness_label.setText(f"{thickness_factor:.1f}")
|
|
121
131
|
|
|
122
132
|
# --- ボタンの配置 ---
|
|
123
133
|
buttons = QHBoxLayout()
|
|
@@ -243,11 +253,42 @@ class SettingsDialog(QDialog):
|
|
|
243
253
|
except Exception:
|
|
244
254
|
pass
|
|
245
255
|
|
|
256
|
+
# Add separator after Kekule bonds option
|
|
257
|
+
separator = QFrame()
|
|
258
|
+
separator.setFrameShape(QFrame.Shape.HLine)
|
|
259
|
+
separator.setFrameShadow(QFrame.Shadow.Sunken)
|
|
260
|
+
self.other_form_layout.addRow(separator)
|
|
261
|
+
|
|
246
262
|
# Place the Kekulé option after the always-ask-charge option
|
|
247
263
|
try:
|
|
248
264
|
self.other_form_layout.addRow("Display Kekulé bonds in 3D:", self.kekule_3d_checkbox)
|
|
249
265
|
except Exception:
|
|
250
266
|
pass
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# Aromatic ring circle display option
|
|
270
|
+
self.aromatic_circle_checkbox = QCheckBox()
|
|
271
|
+
self.aromatic_circle_checkbox.setToolTip("When enabled, aromatic rings will be displayed with a circle inside the ring in 3D view.")
|
|
272
|
+
try:
|
|
273
|
+
self.other_form_layout.addRow("Display aromatic rings as circles in 3D:", self.aromatic_circle_checkbox)
|
|
274
|
+
except Exception:
|
|
275
|
+
pass
|
|
276
|
+
|
|
277
|
+
# Aromatic torus thickness factor
|
|
278
|
+
self.aromatic_torus_thickness_slider = QSlider(Qt.Orientation.Horizontal)
|
|
279
|
+
self.aromatic_torus_thickness_slider.setRange(10, 300) # 0.1x to 3.0x
|
|
280
|
+
self.aromatic_torus_thickness_slider.setValue(60) # Default 0.6x
|
|
281
|
+
self.aromatic_torus_thickness_label = QLabel("0.6")
|
|
282
|
+
self.aromatic_torus_thickness_slider.valueChanged.connect(
|
|
283
|
+
lambda v: self.aromatic_torus_thickness_label.setText(f"{v/100:.1f}")
|
|
284
|
+
)
|
|
285
|
+
thickness_layout = QHBoxLayout()
|
|
286
|
+
thickness_layout.addWidget(self.aromatic_torus_thickness_slider)
|
|
287
|
+
thickness_layout.addWidget(self.aromatic_torus_thickness_label)
|
|
288
|
+
try:
|
|
289
|
+
self.other_form_layout.addRow("Aromatic torus thickness (× bond radius):", thickness_layout)
|
|
290
|
+
except Exception:
|
|
291
|
+
pass
|
|
251
292
|
|
|
252
293
|
# Add Other tab to the tab widget
|
|
253
294
|
self.tab_widget.addTab(self.other_widget, "Other")
|
|
@@ -378,6 +419,12 @@ class SettingsDialog(QDialog):
|
|
|
378
419
|
resolution_layout.addWidget(self.bs_resolution_label)
|
|
379
420
|
form_layout.addRow("Resolution (Quality):", resolution_layout)
|
|
380
421
|
|
|
422
|
+
# --- 区切り線(水平ライン) ---
|
|
423
|
+
line = QFrame()
|
|
424
|
+
line.setFrameShape(QFrame.Shape.HLine)
|
|
425
|
+
line.setFrameShadow(QFrame.Shadow.Sunken)
|
|
426
|
+
form_layout.addRow(line)
|
|
427
|
+
|
|
381
428
|
# --- Ball & Stick bond color ---
|
|
382
429
|
self.bs_bond_color_button = QPushButton()
|
|
383
430
|
self.bs_bond_color_button.setFixedSize(36, 24)
|
|
@@ -385,6 +432,11 @@ class SettingsDialog(QDialog):
|
|
|
385
432
|
self.bs_bond_color_button.setToolTip("Choose the uniform bond color for Ball & Stick model (3D)")
|
|
386
433
|
form_layout.addRow("Ball & Stick bond color:", self.bs_bond_color_button)
|
|
387
434
|
|
|
435
|
+
# Use CPK colors for bonds option
|
|
436
|
+
self.bs_use_cpk_bond_checkbox = QCheckBox()
|
|
437
|
+
self.bs_use_cpk_bond_checkbox.setToolTip("If checked, bonds will be colored using the atom colors (split bonds). If unchecked, a uniform color is used.")
|
|
438
|
+
form_layout.addRow("Use CPK colors for bonds:", self.bs_use_cpk_bond_checkbox)
|
|
439
|
+
|
|
388
440
|
self.tab_widget.addTab(ball_stick_widget, "Ball & Stick")
|
|
389
441
|
|
|
390
442
|
def create_cpk_tab(self):
|
|
@@ -511,17 +563,7 @@ class SettingsDialog(QDialog):
|
|
|
511
563
|
info_label.setStyleSheet("color: #666; font-style: italic; margin-top: 10px;")
|
|
512
564
|
form_layout.addRow(info_label)
|
|
513
565
|
|
|
514
|
-
#
|
|
515
|
-
self.stick_atom_radius_slider = QSlider(Qt.Orientation.Horizontal)
|
|
516
|
-
self.stick_atom_radius_slider.setRange(5, 50) # 0.05 ~ 0.5
|
|
517
|
-
self.stick_atom_radius_label = QLabel("0.15")
|
|
518
|
-
self.stick_atom_radius_slider.valueChanged.connect(lambda v: self.stick_atom_radius_label.setText(f"{v/100:.2f}"))
|
|
519
|
-
atom_radius_layout = QHBoxLayout()
|
|
520
|
-
atom_radius_layout.addWidget(self.stick_atom_radius_slider)
|
|
521
|
-
atom_radius_layout.addWidget(self.stick_atom_radius_label)
|
|
522
|
-
form_layout.addRow("Atom Radius:", atom_radius_layout)
|
|
523
|
-
|
|
524
|
-
# ボンド半径
|
|
566
|
+
# ボンド半径(原子半径も同じ値を使用)
|
|
525
567
|
self.stick_bond_radius_slider = QSlider(Qt.Orientation.Horizontal)
|
|
526
568
|
self.stick_bond_radius_slider.setRange(5, 50) # 0.05 ~ 0.5
|
|
527
569
|
self.stick_bond_radius_label = QLabel("0.15")
|
|
@@ -619,6 +661,8 @@ class SettingsDialog(QDialog):
|
|
|
619
661
|
'skip_chemistry_checks': self.default_settings.get('skip_chemistry_checks', False),
|
|
620
662
|
'display_kekule_3d': self.default_settings.get('display_kekule_3d', False),
|
|
621
663
|
'always_ask_charge': self.default_settings.get('always_ask_charge', False),
|
|
664
|
+
'display_aromatic_circles_3d': self.default_settings.get('display_aromatic_circles_3d', False),
|
|
665
|
+
'aromatic_torus_thickness_factor': self.default_settings.get('aromatic_torus_thickness_factor', 0.6),
|
|
622
666
|
},
|
|
623
667
|
"Ball & Stick": {
|
|
624
668
|
'ball_stick_atom_scale': self.default_settings['ball_stick_atom_scale'],
|
|
@@ -627,11 +671,14 @@ class SettingsDialog(QDialog):
|
|
|
627
671
|
'ball_stick_double_bond_offset_factor': self.default_settings.get('ball_stick_double_bond_offset_factor', 2.0),
|
|
628
672
|
'ball_stick_triple_bond_offset_factor': self.default_settings.get('ball_stick_triple_bond_offset_factor', 2.0),
|
|
629
673
|
'ball_stick_double_bond_radius_factor': self.default_settings.get('ball_stick_double_bond_radius_factor', 0.8),
|
|
630
|
-
'ball_stick_triple_bond_radius_factor': self.default_settings.get('ball_stick_triple_bond_radius_factor', 0.75)
|
|
674
|
+
'ball_stick_triple_bond_radius_factor': self.default_settings.get('ball_stick_triple_bond_radius_factor', 0.75),
|
|
675
|
+
'ball_stick_use_cpk_bond_color': self.default_settings['ball_stick_use_cpk_bond_color'],
|
|
676
|
+
'ball_stick_bond_color': self.default_settings.get('ball_stick_bond_color', '#7F7F7F')
|
|
631
677
|
},
|
|
632
678
|
"CPK (Space-filling)": {
|
|
633
679
|
'cpk_atom_scale': self.default_settings['cpk_atom_scale'],
|
|
634
680
|
'cpk_resolution': self.default_settings['cpk_resolution'],
|
|
681
|
+
'cpk_colors': {}
|
|
635
682
|
},
|
|
636
683
|
"Wireframe": {
|
|
637
684
|
'wireframe_bond_radius': self.default_settings['wireframe_bond_radius'],
|
|
@@ -642,7 +689,6 @@ class SettingsDialog(QDialog):
|
|
|
642
689
|
'wireframe_triple_bond_radius_factor': self.default_settings.get('wireframe_triple_bond_radius_factor', 0.75)
|
|
643
690
|
},
|
|
644
691
|
"Stick": {
|
|
645
|
-
'stick_atom_radius': self.default_settings['stick_atom_radius'],
|
|
646
692
|
'stick_bond_radius': self.default_settings['stick_bond_radius'],
|
|
647
693
|
'stick_resolution': self.default_settings['stick_resolution'],
|
|
648
694
|
'stick_double_bond_offset_factor': self.default_settings.get('stick_double_bond_offset_factor', 1.5),
|
|
@@ -665,6 +711,7 @@ class SettingsDialog(QDialog):
|
|
|
665
711
|
|
|
666
712
|
# UIを更新
|
|
667
713
|
self.update_ui_from_settings(updated_settings)
|
|
714
|
+
# CPK tab: do not change parent/settings immediately; let Apply/OK persist any changes
|
|
668
715
|
|
|
669
716
|
# ユーザーへのフィードバック
|
|
670
717
|
QMessageBox.information(self, "Reset Complete", f"Settings for '{tab_name}' tab have been reset to defaults.")
|
|
@@ -785,7 +832,6 @@ class SettingsDialog(QDialog):
|
|
|
785
832
|
'wireframe_bond_radius': self.wf_bond_radius_slider.value() / 100.0,
|
|
786
833
|
'wireframe_resolution': self.wf_resolution_slider.value(),
|
|
787
834
|
# Stick settings
|
|
788
|
-
'stick_atom_radius': self.stick_atom_radius_slider.value() / 100.0,
|
|
789
835
|
'stick_bond_radius': self.stick_bond_radius_slider.value() / 100.0,
|
|
790
836
|
'stick_resolution': self.stick_resolution_slider.value(),
|
|
791
837
|
# Multi-bond settings (per-model)
|
|
@@ -801,6 +847,17 @@ class SettingsDialog(QDialog):
|
|
|
801
847
|
'stick_triple_bond_offset_factor': self.stick_triple_offset_slider.value() / 100.0,
|
|
802
848
|
'stick_double_bond_radius_factor': self.stick_double_radius_slider.value() / 100.0,
|
|
803
849
|
'stick_triple_bond_radius_factor': self.stick_triple_radius_slider.value() / 100.0,
|
|
850
|
+
# Projection mode
|
|
851
|
+
'projection_mode': self.projection_combo.currentText(),
|
|
852
|
+
# Kekule / aromatic / torus settings
|
|
853
|
+
'display_kekule_3d': self.kekule_3d_checkbox.isChecked(),
|
|
854
|
+
'display_aromatic_circles_3d': self.aromatic_circle_checkbox.isChecked(),
|
|
855
|
+
'aromatic_torus_thickness_factor': self.aromatic_torus_thickness_slider.value() / 100.0,
|
|
856
|
+
'skip_chemistry_checks': self.skip_chem_checks_checkbox.isChecked(),
|
|
857
|
+
'always_ask_charge': self.always_ask_charge_checkbox.isChecked(),
|
|
858
|
+
# Ball & Stick bond color and use-cpk option
|
|
859
|
+
'ball_stick_bond_color': getattr(self, 'bs_bond_color', self.default_settings.get('ball_stick_bond_color')),
|
|
860
|
+
'ball_stick_use_cpk_bond_color': self.bs_use_cpk_bond_checkbox.isChecked(),
|
|
804
861
|
}
|
|
805
862
|
|
|
806
863
|
def reset_to_defaults(self):
|
|
@@ -854,6 +911,9 @@ class SettingsDialog(QDialog):
|
|
|
854
911
|
except Exception:
|
|
855
912
|
pass
|
|
856
913
|
|
|
914
|
+
# Ball & Stick CPK bond color option
|
|
915
|
+
self.bs_use_cpk_bond_checkbox.setChecked(settings_dict.get('ball_stick_use_cpk_bond_color', self.default_settings['ball_stick_use_cpk_bond_color']))
|
|
916
|
+
|
|
857
917
|
# CPK設定
|
|
858
918
|
cpk_atom_scale = int(settings_dict.get('cpk_atom_scale', self.default_settings['cpk_atom_scale']) * 100)
|
|
859
919
|
self.cpk_atom_scale_slider.setValue(cpk_atom_scale)
|
|
@@ -871,10 +931,6 @@ class SettingsDialog(QDialog):
|
|
|
871
931
|
self.wf_resolution_label.setText(str(settings_dict.get('wireframe_resolution', self.default_settings['wireframe_resolution'])))
|
|
872
932
|
|
|
873
933
|
# Stick設定
|
|
874
|
-
stick_atom_radius = int(settings_dict.get('stick_atom_radius', self.default_settings['stick_atom_radius']) * 100)
|
|
875
|
-
self.stick_atom_radius_slider.setValue(stick_atom_radius)
|
|
876
|
-
self.stick_atom_radius_label.setText(f"{stick_atom_radius/100:.2f}")
|
|
877
|
-
|
|
878
934
|
stick_bond_radius = int(settings_dict.get('stick_bond_radius', self.default_settings['stick_bond_radius']) * 100)
|
|
879
935
|
self.stick_bond_radius_slider.setValue(stick_bond_radius)
|
|
880
936
|
self.stick_bond_radius_label.setText(f"{stick_bond_radius/100:.2f}")
|
|
@@ -944,6 +1000,14 @@ class SettingsDialog(QDialog):
|
|
|
944
1000
|
self.kekule_3d_checkbox.setChecked(settings_dict.get('display_kekule_3d', self.default_settings.get('display_kekule_3d', False)))
|
|
945
1001
|
# always ask for charge on XYZ imports
|
|
946
1002
|
self.always_ask_charge_checkbox.setChecked(settings_dict.get('always_ask_charge', self.default_settings.get('always_ask_charge', False)))
|
|
1003
|
+
# Aromatic ring circle display and torus thickness factor
|
|
1004
|
+
self.aromatic_circle_checkbox.setChecked(settings_dict.get('display_aromatic_circles_3d', self.default_settings.get('display_aromatic_circles_3d', False)))
|
|
1005
|
+
thickness_factor = float(settings_dict.get('aromatic_torus_thickness_factor', self.default_settings.get('aromatic_torus_thickness_factor', 0.6)))
|
|
1006
|
+
try:
|
|
1007
|
+
self.aromatic_torus_thickness_slider.setValue(int(thickness_factor * 100))
|
|
1008
|
+
self.aromatic_torus_thickness_label.setText(f"{thickness_factor:.1f}")
|
|
1009
|
+
except Exception:
|
|
1010
|
+
pass
|
|
947
1011
|
|
|
948
1012
|
def select_color(self):
|
|
949
1013
|
"""カラーピッカーを開き、選択された色を内部変数とUIに反映させる"""
|
|
@@ -979,7 +1043,6 @@ class SettingsDialog(QDialog):
|
|
|
979
1043
|
'wireframe_bond_radius': self.wf_bond_radius_slider.value() / 100.0,
|
|
980
1044
|
'wireframe_resolution': self.wf_resolution_slider.value(),
|
|
981
1045
|
# Stick settings
|
|
982
|
-
'stick_atom_radius': self.stick_atom_radius_slider.value() / 100.0,
|
|
983
1046
|
'stick_bond_radius': self.stick_bond_radius_slider.value() / 100.0,
|
|
984
1047
|
'stick_resolution': self.stick_resolution_slider.value(),
|
|
985
1048
|
# Multiple bond offset settings (per-model)
|
|
@@ -996,10 +1059,13 @@ class SettingsDialog(QDialog):
|
|
|
996
1059
|
'stick_double_bond_radius_factor': self.stick_double_radius_slider.value() / 100.0,
|
|
997
1060
|
'stick_triple_bond_radius_factor': self.stick_triple_radius_slider.value() / 100.0,
|
|
998
1061
|
'display_kekule_3d': self.kekule_3d_checkbox.isChecked(),
|
|
1062
|
+
'display_aromatic_circles_3d': self.aromatic_circle_checkbox.isChecked(),
|
|
1063
|
+
'aromatic_torus_thickness_factor': self.aromatic_torus_thickness_slider.value() / 100.0,
|
|
999
1064
|
'skip_chemistry_checks': self.skip_chem_checks_checkbox.isChecked(),
|
|
1000
1065
|
'always_ask_charge': self.always_ask_charge_checkbox.isChecked(),
|
|
1001
1066
|
# Ball & Stick bond color (3D grey/uniform color)
|
|
1002
1067
|
'ball_stick_bond_color': getattr(self, 'bs_bond_color', self.default_settings.get('ball_stick_bond_color', '#7F7F7F')),
|
|
1068
|
+
'ball_stick_use_cpk_bond_color': self.bs_use_cpk_bond_checkbox.isChecked(),
|
|
1003
1069
|
}
|
|
1004
1070
|
|
|
1005
1071
|
def pick_bs_bond_color(self):
|
|
@@ -23,6 +23,7 @@ except Exception:
|
|
|
23
23
|
from modules.constants import VERSION, CPK_COLORS
|
|
24
24
|
import os
|
|
25
25
|
import json
|
|
26
|
+
import logging
|
|
26
27
|
|
|
27
28
|
class UserTemplateDialog(QDialog):
|
|
28
29
|
"""ユーザーテンプレート管理ダイアログ"""
|
|
@@ -106,7 +107,7 @@ class UserTemplateDialog(QDialog):
|
|
|
106
107
|
elif hasattr(child, 'refit_view'):
|
|
107
108
|
child.refit_view()
|
|
108
109
|
except Exception as e:
|
|
109
|
-
|
|
110
|
+
logging.warning(f"Warning: Failed to refit template previews: {e}")
|
|
110
111
|
|
|
111
112
|
def showEvent(self, event):
|
|
112
113
|
"""ダイアログ表示時にプレビューを適切にフィット"""
|
|
@@ -136,7 +137,7 @@ class UserTemplateDialog(QDialog):
|
|
|
136
137
|
template_data['filepath'] = filepath
|
|
137
138
|
self.user_templates.append(template_data)
|
|
138
139
|
except Exception as e:
|
|
139
|
-
|
|
140
|
+
logging.error(f"Error loading user templates: {e}")
|
|
140
141
|
|
|
141
142
|
self.update_template_grid()
|
|
142
143
|
|
|
@@ -146,7 +147,7 @@ class UserTemplateDialog(QDialog):
|
|
|
146
147
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
147
148
|
return json.load(f)
|
|
148
149
|
except Exception as e:
|
|
149
|
-
|
|
150
|
+
logging.error(f"Error loading template file {filepath}: {e}")
|
|
150
151
|
return None
|
|
151
152
|
|
|
152
153
|
def save_template_file(self, filepath, template_data):
|
|
@@ -156,7 +157,7 @@ class UserTemplateDialog(QDialog):
|
|
|
156
157
|
json.dump(template_data, f, indent=2, ensure_ascii=False)
|
|
157
158
|
return True
|
|
158
159
|
except Exception as e:
|
|
159
|
-
|
|
160
|
+
logging.error(f"Error saving template file {filepath}: {e}")
|
|
160
161
|
return False
|
|
161
162
|
|
|
162
163
|
def update_template_grid(self):
|
|
@@ -253,7 +254,7 @@ class UserTemplateDialog(QDialog):
|
|
|
253
254
|
if view and not rect.isEmpty():
|
|
254
255
|
view.fitInView(rect, Qt.AspectRatioMode.KeepAspectRatio)
|
|
255
256
|
except Exception as e:
|
|
256
|
-
|
|
257
|
+
logging.warning(f"Warning: Failed to fit preview view: {e}")
|
|
257
258
|
|
|
258
259
|
def draw_template_preview(self, scene, template_data, view_size=None):
|
|
259
260
|
"""テンプレートプレビューを描画 - fitInView縮小率に基づく動的スケーリング"""
|
|
@@ -303,7 +304,7 @@ class UserTemplateDialog(QDialog):
|
|
|
303
304
|
scale_factor = 4.0
|
|
304
305
|
|
|
305
306
|
# Debug info (can be removed in production)
|
|
306
|
-
#
|
|
307
|
+
# logging.debug(f"Mol size: {mol_size:.1f}, Fit scale: {fit_scale:.3f}, Scale factor: {scale_factor:.2f}")
|
|
307
308
|
else:
|
|
308
309
|
scale_factor = 1.0
|
|
309
310
|
|
|
@@ -481,7 +482,7 @@ class UserTemplateDialog(QDialog):
|
|
|
481
482
|
except Exception:
|
|
482
483
|
pass
|
|
483
484
|
except Exception as e:
|
|
484
|
-
|
|
485
|
+
logging.warning(f"Warning: Failed to switch main window to template mode: {e}")
|
|
485
486
|
|
|
486
487
|
def use_template(self, template_data):
|
|
487
488
|
"""テンプレートを使用(エディタに適用)"""
|
|
@@ -518,7 +519,7 @@ class UserTemplateDialog(QDialog):
|
|
|
518
519
|
# Mark selected and keep dialog open
|
|
519
520
|
self.selected_template = template_data
|
|
520
521
|
except Exception as e:
|
|
521
|
-
|
|
522
|
+
logging.warning(f"Warning: Failed to switch main window to template mode: {e}")
|
|
522
523
|
|
|
523
524
|
# Don't close dialog - keep it open for easy template switching
|
|
524
525
|
# self.accept()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MoleditPy-linux
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18.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
|
|
@@ -684,7 +684,6 @@ Classifier: Programming Language :: Python :: 3
|
|
|
684
684
|
Classifier: Operating System :: OS Independent
|
|
685
685
|
Classifier: Intended Audience :: Science/Research
|
|
686
686
|
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
687
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
688
687
|
Classifier: Programming Language :: Python :: 3.9
|
|
689
688
|
Classifier: Programming Language :: Python :: 3.10
|
|
690
689
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -3,53 +3,53 @@ moleditpy_linux/__main__.py,sha256=bYu_h7lhc6PIl1-I_VI4_Q5MdBHmVrMiO4DYsy9jbiY,8
|
|
|
3
3
|
moleditpy_linux/main.py,sha256=0D8_CXe4xdgqlu2TWoT2pi35K9y2b4ilFj6LWD9Qk7w,1178
|
|
4
4
|
moleditpy_linux/modules/__init__.py,sha256=PFwvuEKXsgQlHTYL8oT5sTeo22gR0XmQcySp7kOTtqk,1396
|
|
5
5
|
moleditpy_linux/modules/about_dialog.py,sha256=zkR-w0vtqLH1Y0baQaoTb0tYmVamT4ztEMBdIANKKvc,3693
|
|
6
|
-
moleditpy_linux/modules/align_plane_dialog.py,sha256=
|
|
7
|
-
moleditpy_linux/modules/alignment_dialog.py,sha256=
|
|
6
|
+
moleditpy_linux/modules/align_plane_dialog.py,sha256=A4sGfnpWSLM5v4g2ADUVmZnWtKEaQxeGQk7ZRLTRj58,11944
|
|
7
|
+
moleditpy_linux/modules/alignment_dialog.py,sha256=lZOWo1Y7uKt31nxZAguNDHNZxKww_aLcg-JPilM2CPQ,11419
|
|
8
8
|
moleditpy_linux/modules/analysis_window.py,sha256=zjP5ipSTpKw8oLr1eKdoxW8Bk1SslGlPqsVucD-x_5w,9403
|
|
9
|
-
moleditpy_linux/modules/angle_dialog.py,sha256=
|
|
9
|
+
moleditpy_linux/modules/angle_dialog.py,sha256=ytuE5VqT0dskgob1x08B6VW06qnslgCdAs_dwS2ANgY,17837
|
|
10
10
|
moleditpy_linux/modules/atom_item.py,sha256=u8ge6B1M9sOGobfzg3tp1-EGXtEUmvdee7Fx6msg8Wk,15566
|
|
11
|
-
moleditpy_linux/modules/bond_item.py,sha256=
|
|
12
|
-
moleditpy_linux/modules/bond_length_dialog.py,sha256=
|
|
11
|
+
moleditpy_linux/modules/bond_item.py,sha256=eVkEeKvM4igYI67DYxpey3FllqDyt_iWDo4VPYMhaPk,19137
|
|
12
|
+
moleditpy_linux/modules/bond_length_dialog.py,sha256=k5x_DhK9Q8CSwouKhEo_kLRRdaYHDaK84KDNmuDNLvY,14868
|
|
13
13
|
moleditpy_linux/modules/calculation_worker.py,sha256=KiGQY7i-QCQofEoE0r65KoQgpEGFcbhmxWv6egfkUdc,42324
|
|
14
14
|
moleditpy_linux/modules/color_settings_dialog.py,sha256=Ow44BhCOLo0AFb6klO001k6B4drOgKX9DeNBQhZLp5o,15474
|
|
15
|
-
moleditpy_linux/modules/constants.py,sha256=
|
|
16
|
-
moleditpy_linux/modules/constrained_optimization_dialog.py,sha256=
|
|
15
|
+
moleditpy_linux/modules/constants.py,sha256=BmnH8wNO4QnsenarqQeN9pnaHyIeIo6PJJyT2HFWLfc,4703
|
|
16
|
+
moleditpy_linux/modules/constrained_optimization_dialog.py,sha256=IEdNVhFoNSEMeA5ABpUH9Q88-YzDXFloQM2gwnPwnHY,30150
|
|
17
17
|
moleditpy_linux/modules/custom_interactor_style.py,sha256=NjsXE2a43IDNEanZBlcG9eR4ZIERT1MsQC6lbfesapQ,38453
|
|
18
18
|
moleditpy_linux/modules/custom_qt_interactor.py,sha256=MFaTuDh-FPeFBS4303CqxsxmsOIOW4QXUz6USwI8PHQ,2451
|
|
19
19
|
moleditpy_linux/modules/dialog3_d_picking_mixin.py,sha256=2Sut0J5ltXMtrUJ9R3o1oZ4ysed27mdSIqLpWxmGdyM,5037
|
|
20
|
-
moleditpy_linux/modules/dihedral_dialog.py,sha256=
|
|
20
|
+
moleditpy_linux/modules/dihedral_dialog.py,sha256=rgry7LqyX9JMAR7d82QSroTPoKT3xz18EgKN1GzYZx4,18088
|
|
21
21
|
moleditpy_linux/modules/main_window.py,sha256=bWgYP3EMOAcy1fnjg5DTXHb2d7Xm6zKQtFcleYjg7Ac,35789
|
|
22
|
-
moleditpy_linux/modules/main_window_app_state.py,sha256=
|
|
23
|
-
moleditpy_linux/modules/main_window_compute.py,sha256=
|
|
22
|
+
moleditpy_linux/modules/main_window_app_state.py,sha256=ONdjo-ZAPdat1_ToFodzuUep3c8qbKRPX6glnY24c9o,33602
|
|
23
|
+
moleditpy_linux/modules/main_window_compute.py,sha256=DsyMvGD2gnB-9XC6SU-ICuScyyQxubfaDYAk8hkY-vk,51911
|
|
24
24
|
moleditpy_linux/modules/main_window_dialog_manager.py,sha256=S1ROCWqzB2uVSKHY4o5CbTtJAEjSyEXGPC1AgmdVgK4,20065
|
|
25
|
-
moleditpy_linux/modules/main_window_edit_3d.py,sha256=
|
|
25
|
+
moleditpy_linux/modules/main_window_edit_3d.py,sha256=uY203adPg3CLyAdbG2NCThG2Am0WduzPDan9rXAlc14,19841
|
|
26
26
|
moleditpy_linux/modules/main_window_edit_actions.py,sha256=lUFxNFTUQzeXN8CNlb4_4S9j4M1EEq8kpJmh9dCzM3M,64818
|
|
27
|
-
moleditpy_linux/modules/main_window_export.py,sha256=
|
|
28
|
-
moleditpy_linux/modules/main_window_main_init.py,sha256=
|
|
29
|
-
moleditpy_linux/modules/main_window_molecular_parsers.py,sha256=
|
|
30
|
-
moleditpy_linux/modules/main_window_project_io.py,sha256=
|
|
27
|
+
moleditpy_linux/modules/main_window_export.py,sha256=e0HA_jeaokIOBunQqGxUn5QKdniCmE8GrsE1Igy6zm8,38351
|
|
28
|
+
moleditpy_linux/modules/main_window_main_init.py,sha256=Ox6P8MQtEnOw47NWdgOmxNNSAFgR6Vv8My71gNvj8RY,75608
|
|
29
|
+
moleditpy_linux/modules/main_window_molecular_parsers.py,sha256=Ex4-urYsKf6PyHp4XToOhgXzuYWa_n7q--QmHci4OCU,48401
|
|
30
|
+
moleditpy_linux/modules/main_window_project_io.py,sha256=q1vEmWQDqla32HVkmk8-j0OY9ut5TI5NJ4ikahewkEo,17259
|
|
31
31
|
moleditpy_linux/modules/main_window_string_importers.py,sha256=mQVDv2Dj4MwnPgMRe2IqdAAKnB_quE6QfYeAgCjfv28,10892
|
|
32
32
|
moleditpy_linux/modules/main_window_ui_manager.py,sha256=p2KPzAj0GK9ZWP7SbAg0jGrmKeLaLC0X7l9ISC4GVu4,22256
|
|
33
|
-
moleditpy_linux/modules/main_window_view_3d.py,sha256=
|
|
34
|
-
moleditpy_linux/modules/main_window_view_loaders.py,sha256=
|
|
33
|
+
moleditpy_linux/modules/main_window_view_3d.py,sha256=MQCW2GnqGUpdJO4-GeR_18z7dS5K8C2GzKY9Nf8Nm8U,69627
|
|
34
|
+
moleditpy_linux/modules/main_window_view_loaders.py,sha256=Dbdgv4TY_ZkX8Qyaevwr-mBJYJ59CBzRTEks-U1FiGw,14462
|
|
35
35
|
moleditpy_linux/modules/mirror_dialog.py,sha256=c3v4qY6R4FAljzk4EPaDjL9ZdZMjLQSFLqDMXz2fBUk,4696
|
|
36
36
|
moleditpy_linux/modules/molecular_data.py,sha256=8gE9ByYg3kSBfb1zANsyad_BVBTm6WOLF7NsZIYuG2E,13250
|
|
37
|
-
moleditpy_linux/modules/molecule_scene.py,sha256=
|
|
37
|
+
moleditpy_linux/modules/molecule_scene.py,sha256=Ced3-U_03epwb1yL2QToq9MtILN4qCYDe0qpayHMWAE,94997
|
|
38
38
|
moleditpy_linux/modules/move_group_dialog.py,sha256=65HVXTJSaQ9lp03XFhI1l7OzUsXmH_aqd8OgwjpjfGg,27174
|
|
39
39
|
moleditpy_linux/modules/periodic_table_dialog.py,sha256=ItEZUts1XCietz9paY-spvbzxh6SXak3GnikwqkHZCw,4006
|
|
40
|
-
moleditpy_linux/modules/planarize_dialog.py,sha256=
|
|
41
|
-
moleditpy_linux/modules/settings_dialog.py,sha256=
|
|
40
|
+
moleditpy_linux/modules/planarize_dialog.py,sha256=yY8o-SxT8vGEHVWnjDTXecRv5NUaEejEsXH-836Xk8g,8681
|
|
41
|
+
moleditpy_linux/modules/settings_dialog.py,sha256=Nr7yE8UmYRi3VObWvRlrnv0DnjSjmYXbvqryZ02O12k,65348
|
|
42
42
|
moleditpy_linux/modules/template_preview_item.py,sha256=Ks3C35pYFuLT5G4fsloI7ljE6ESXoYyGvLkM22qcmt0,6673
|
|
43
43
|
moleditpy_linux/modules/template_preview_view.py,sha256=4OCHZDO51BvJpKdfrBWJ4_4WfLfFSKxsVIyf7I-Kj2E,3350
|
|
44
44
|
moleditpy_linux/modules/translation_dialog.py,sha256=aWlgTR9mtEMbzGIY1SoQhDltsX-01LtCxjqy5NWtGuA,14663
|
|
45
|
-
moleditpy_linux/modules/user_template_dialog.py,sha256=
|
|
45
|
+
moleditpy_linux/modules/user_template_dialog.py,sha256=L2D2AUokh7flqHiCBXWNcVG9Z8RgjXnlUhi2ZO6fgVg,28312
|
|
46
46
|
moleditpy_linux/modules/zoomable_view.py,sha256=hjwljui13QpvjvxJHY4Evot4jMQvxRBQUNH5HUlyFOk,5966
|
|
47
47
|
moleditpy_linux/modules/assets/icon.icns,sha256=wD5R6-Vw7K662tVKhu2E1ImN0oUuyAP4youesEQsn9c,139863
|
|
48
48
|
moleditpy_linux/modules/assets/icon.ico,sha256=RfgFcx7-dHY_2STdsOQCQziY5SNhDr3gPnjO6jzEDPI,147975
|
|
49
49
|
moleditpy_linux/modules/assets/icon.png,sha256=kCFN1WacYIdy0GN6SFEbNA00ef39pCczBnFdkkBI8Bs,147110
|
|
50
|
-
moleditpy_linux-1.
|
|
51
|
-
moleditpy_linux-1.
|
|
52
|
-
moleditpy_linux-1.
|
|
53
|
-
moleditpy_linux-1.
|
|
54
|
-
moleditpy_linux-1.
|
|
55
|
-
moleditpy_linux-1.
|
|
50
|
+
moleditpy_linux-1.18.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
51
|
+
moleditpy_linux-1.18.1.dist-info/METADATA,sha256=Af61_lPyAZ-3Os7uWmdbsb7raba3VK_ynPdfrUTLwZk,58683
|
|
52
|
+
moleditpy_linux-1.18.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
53
|
+
moleditpy_linux-1.18.1.dist-info/entry_points.txt,sha256=-OzipSi__yVwlimNtu3eiRP5t5UMg55Cs0udyhXYiyw,60
|
|
54
|
+
moleditpy_linux-1.18.1.dist-info/top_level.txt,sha256=qyqe-hDYL6CXyin9E5Me5rVl3PG84VqiOjf9bQvfJLs,16
|
|
55
|
+
moleditpy_linux-1.18.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|