finalcif 155__tar.gz → 157__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.
- {finalcif-155 → finalcif-157}/.gitattributes +3 -0
- {finalcif-155 → finalcif-157}/.gitignore +8 -0
- finalcif-157/.python-version +1 -0
- {finalcif-155 → finalcif-157}/PKG-INFO +4 -4
- finalcif-157/finalcif/__init__.py +2 -0
- {finalcif-155 → finalcif-157}/finalcif/appwindow.py +78 -37
- {finalcif-155 → finalcif-157}/finalcif/cif/all_cif_dicts.py +5 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/checkcif/checkcif.py +4 -1
- {finalcif-155 → finalcif-157}/finalcif/cif/cif_order.py +15 -11
- {finalcif-155 → finalcif-157}/finalcif/ciforder/order_ui.py +1 -3
- {finalcif-155 → finalcif-157}/finalcif/equip_property/author_loop_templates.py +2 -2
- {finalcif-155 → finalcif-157}/finalcif/equip_property/properties.py +6 -7
- {finalcif-155 → finalcif-157}/finalcif/gui/dialogs.py +12 -2
- {finalcif-155 → finalcif-157}/finalcif/gui/file_editor.py +12 -5
- {finalcif-155 → finalcif-157}/finalcif/gui/finalcif_gui_ui.py +895 -803
- {finalcif-155 → finalcif-157}/finalcif/gui/finalcif_gui_ui.ui +343 -188
- {finalcif-155 → finalcif-157}/finalcif/gui/import_selector_ui.py +2 -4
- {finalcif-155 → finalcif-157}/finalcif/gui/loop_creator_ui.py +0 -2
- {finalcif-155 → finalcif-157}/finalcif/gui/loops.py +0 -1
- {finalcif-155 → finalcif-157}/finalcif/gui/new_key_dialog_ui.py +0 -2
- finalcif-157/finalcif/gui/syntax_highlighter.py +150 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/text_templates_ui.py +0 -2
- finalcif-157/finalcif/gui/vzs_viewer.py +182 -0
- {finalcif-155 → finalcif-157}/finalcif/report/gui/mainwindow.py +0 -2
- {finalcif-155 → finalcif-157}/finalcif/report/references.py +1 -1
- {finalcif-155 → finalcif-157}/finalcif/report/templated_report.py +30 -36
- {finalcif-155 → finalcif-157}/finalcif/template/report.tmpl +45 -21
- finalcif-157/finalcif/template/report_default.docx +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/misc.py +1 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/options.py +12 -4
- {finalcif-155 → finalcif-157}/finalcif/tools/shred.py +1 -2
- {finalcif-155 → finalcif-157}/finalcif.exe +0 -0
- {finalcif-155 → finalcif-157}/platon/README.txt +11 -0
- finalcif-157/pylock.toml +892 -0
- {finalcif-155 → finalcif-157}/pyproject.toml +16 -6
- {finalcif-155 → finalcif-157}/requirements.txt +4 -4
- {finalcif-155 → finalcif-157}/uv.lock +290 -141
- finalcif-155/.python-version +0 -1
- finalcif-155/finalcif/__init__.py +0 -2
- finalcif-155/finalcif/template/report_default.docx +0 -0
- finalcif-155/install_requirements +0 -9
- finalcif-155/install_requirements.bat +0 -13
- {finalcif-155 → finalcif-157}/.ruff.toml +0 -0
- {finalcif-155 → finalcif-157}/.run/Make Documentation MAC.run.xml +0 -0
- {finalcif-155 → finalcif-157}/.run/compile_ui_files.run.xml +0 -0
- {finalcif-155 → finalcif-157}/.run/make documentation Windows.run.xml +0 -0
- {finalcif-155 → finalcif-157}/CODE_OF_CONDUCT.md +0 -0
- {finalcif-155 → finalcif-157}/CONTRIBUTING.md +0 -0
- {finalcif-155 → finalcif-157}/Finalcif_installer_win.spec +0 -0
- {finalcif-155 → finalcif-157}/Finalcif_linux_onefile.spec +0 -0
- {finalcif-155 → finalcif-157}/Finalcif_mac.spec +0 -0
- {finalcif-155 → finalcif-157}/Hydrogen_solution_type.cif +0 -0
- {finalcif-155 → finalcif-157}/LICENSE +0 -0
- {finalcif-155 → finalcif-157}/README.md +0 -0
- {finalcif-155 → finalcif-157}/finalcif/app_path.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/atoms.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/checkcif/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cif_dict_foo.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cif_file_io.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/deposit.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/deposit_check.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/deposition_list.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/doi.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/upload.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/cod/website_parser.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/core_dict.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/hkl.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/modulation_dict.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/powder_dict.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/reference.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/restraints_dict.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/text.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/cif/twin_dict.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/ciforder/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/ciforder/order.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/ciforder/order_ui.ui +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/bruker_data.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/bruker_frame.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/ccdc_mail.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/data.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/p4p_reader.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/sadabs.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/saint.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/shelx_lst.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/datafiles/utils.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/displaymol/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/displaymol/molecule2D.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/displaymol/sdm.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/displaymol/vtk_molecule.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/equip_property/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/equip_property/equipment.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/equip_property/tools.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/finalcif_start.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/block_combobox.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/combobox.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/custom_classes.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/edit_button.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/equipmenttable.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/import_selector.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/import_selector_ui.ui +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/loop_creator.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/loop_creator_ui.ui +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/mainstackwidget.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/mixins.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/new_key_dialog.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/new_key_dialog_ui.ui +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/plaintextedit.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/playground.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/propertytable.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/spell_check_edit.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/text_templates_ui.ui +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/text_value_editor.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/validators.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/gui/vrf_classes.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/finalcif.png +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/finalcif2.ico +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/finalcif2.png +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/multitable.ico +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/multitable.png +0 -0
- {finalcif-155 → finalcif-157}/finalcif/icon/multitable.xcf +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/archive_report.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/gui/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/gui/mainwindow.ui +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/mtools.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/report_text.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/symm.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/report/tables.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/bootstrap/bootstrap.min.css +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/machines/D8_VENTURE.cif +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/mathml2omml.xsl +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/template1.docx +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/template_for_multitable.docx +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/template_text.docx +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/template_without_text.docx +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/templates.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/xsl/convert.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/template/xsl/xmltohtml.xsl +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/__init__.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/chemparse.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/download.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/dsrmath.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/platon.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/pupdate.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/settings.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/space_groups.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/spgr_format.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/statusbar.py +0 -0
- {finalcif-155 → finalcif-157}/finalcif/tools/sumformula.py +0 -0
- {finalcif-155 → finalcif-157}/platon/compile_platon.bat +0 -0
- {finalcif-155 → finalcif-157}/platon/platon_special.exe +0 -0
- {finalcif-155 → finalcif-157}/platon/platon_special.f +0 -0
- {finalcif-155 → finalcif-157}/requirements_devel.txt +0 -0
- {finalcif-155 → finalcif-157}/requirements_doku.txt +0 -0
- {finalcif-155 → finalcif-157}/run_finalcif +0 -0
- {finalcif-155 → finalcif-157}/run_finalcif.bat +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_checkcif.png +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_details.png +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_loops.png +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_loops2.png +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_main.png +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_report.png +0 -0
- {finalcif-155 → finalcif-157}/screenshots/finalcif_responses.png +0 -0
- {finalcif-155 → finalcif-157}/update.exe +0 -0
|
@@ -227,3 +227,11 @@ tests/examples/work/cu_BruecknerJK_153F40_0m.lxt
|
|
|
227
227
|
finalcif_keys_order.cif
|
|
228
228
|
!/.python-version
|
|
229
229
|
/platon/*.mod
|
|
230
|
+
/work/test.aux
|
|
231
|
+
/work/test.pdf
|
|
232
|
+
/work/test.synctex.gz
|
|
233
|
+
/work/test.tex
|
|
234
|
+
/tests/examples/work/cu_BruecknerJK_153F40_0m-finalcif-1.zip
|
|
235
|
+
/tests/examples/work/cu_BruecknerJK_153F40_0m-finalcif-2.zip
|
|
236
|
+
/tests/examples/work/cu_BruecknerJK_153F40_0m_video-finalcif.png
|
|
237
|
+
/tests/examples/work/report_cu_BruecknerJK_153F40_0m-finalcif.html
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cpython@3.14
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: finalcif
|
|
3
|
-
Version:
|
|
3
|
+
Version: 157
|
|
4
4
|
Summary: CIF file editor
|
|
5
5
|
Project-URL: Homepage, https://dkratzert.de/finalcif.html
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/dkratzert/FinalCif/issues
|
|
@@ -16,11 +16,11 @@ Requires-Dist: certifi
|
|
|
16
16
|
Requires-Dist: chardet
|
|
17
17
|
Requires-Dist: charset-normalizer
|
|
18
18
|
Requires-Dist: crossrefapi
|
|
19
|
-
Requires-Dist: docxtpl
|
|
20
|
-
Requires-Dist: gemmi
|
|
19
|
+
Requires-Dist: docxtpl[subdoc]>=0.20.2
|
|
20
|
+
Requires-Dist: gemmi>=0.7.5
|
|
21
21
|
Requires-Dist: hatchling
|
|
22
22
|
Requires-Dist: html2text
|
|
23
|
-
Requires-Dist: lxml
|
|
23
|
+
Requires-Dist: lxml==6.0.2
|
|
24
24
|
Requires-Dist: numpy
|
|
25
25
|
Requires-Dist: packaging
|
|
26
26
|
Requires-Dist: pefile
|
|
@@ -5,14 +5,21 @@
|
|
|
5
5
|
# and you think this stuff is worth it, you can buy me a beer in return.
|
|
6
6
|
# ----------------------------------------------------------------------------
|
|
7
7
|
import os
|
|
8
|
+
import pickle
|
|
8
9
|
import subprocess
|
|
9
10
|
import sys
|
|
10
11
|
import threading
|
|
11
12
|
import time
|
|
13
|
+
import warnings
|
|
12
14
|
from contextlib import suppress
|
|
13
15
|
from datetime import datetime
|
|
14
16
|
from math import sin, radians
|
|
15
17
|
from pathlib import Path, WindowsPath
|
|
18
|
+
from typing import cast
|
|
19
|
+
|
|
20
|
+
from finalcif.gui.vzs_viewer import VZSImageViewer
|
|
21
|
+
|
|
22
|
+
warnings.filterwarnings("ignore", category=RuntimeWarning, module="shibokensupport.signature.parser")
|
|
16
23
|
|
|
17
24
|
import gemmi
|
|
18
25
|
|
|
@@ -43,7 +50,8 @@ from finalcif.gui.custom_classes import Column, MyTableWidgetItem, light_green,
|
|
|
43
50
|
white
|
|
44
51
|
from finalcif.gui.dialogs import show_update_warning, unable_to_open_message, show_general_warning, \
|
|
45
52
|
cif_file_open_dialog, \
|
|
46
|
-
bad_z_message, show_res_checksum_warning, show_hkl_checksum_warning, cif_file_save_dialog, show_yes_now_question
|
|
53
|
+
bad_z_message, show_res_checksum_warning, show_hkl_checksum_warning, cif_file_save_dialog, show_yes_now_question, \
|
|
54
|
+
video_file_open_dialog
|
|
47
55
|
from finalcif.gui.finalcif_gui_ui import Ui_FinalCifWindow
|
|
48
56
|
from finalcif.gui.import_selector import ImportSelector
|
|
49
57
|
from finalcif.gui.loop_creator import LoopCreator
|
|
@@ -103,6 +111,10 @@ class AppWindow(QMainWindow):
|
|
|
103
111
|
self.ui = Ui_FinalCifWindow()
|
|
104
112
|
self.ui.setupUi(self)
|
|
105
113
|
self.ui.page_MainTable.setParent(self.ui.MainStackedWidget)
|
|
114
|
+
self.fixfont = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.SystemFont.FixedFont)
|
|
115
|
+
self.ui.shelx_TextEdit.setFont(self.fixfont)
|
|
116
|
+
self.ui.shelx_warn_TextEdit.setFont(self.fixfont)
|
|
117
|
+
self.ui.ckf_textedit.setFont(self.fixfont)
|
|
106
118
|
self.settings = FinalCifSettings()
|
|
107
119
|
self.load_fontsize_from_settings()
|
|
108
120
|
self.options = Options(self.ui, self.settings)
|
|
@@ -124,6 +136,9 @@ class AppWindow(QMainWindow):
|
|
|
124
136
|
self.ui.TemplatesStackedWidget.setCurrentIndex(0)
|
|
125
137
|
self.ui.MainStackedWidget.got_to_main_page()
|
|
126
138
|
self.set_initial_button_states()
|
|
139
|
+
self.video = VZSImageViewer(self)
|
|
140
|
+
self.ui.picturesTabWidget.setCurrentIndex(0)
|
|
141
|
+
self.ui.video_vLayout.addWidget(self.video)
|
|
127
142
|
if file:
|
|
128
143
|
self.load_cif_file(file)
|
|
129
144
|
self.load_recent_cifs_list()
|
|
@@ -143,7 +158,9 @@ class AppWindow(QMainWindow):
|
|
|
143
158
|
" Spek, A.L. (2020). Acta Cryst. E76, 1-11.\n"
|
|
144
159
|
" \n"
|
|
145
160
|
" \n"
|
|
146
|
-
" - Recent versions of PLATON may be obtained from: https://platonsoft.nl/xraysoft\n"
|
|
161
|
+
" - Recent versions of PLATON may be obtained from: https://platonsoft.nl/xraysoft\n\n"
|
|
162
|
+
" PLATON is free of charge for Academics.\n"
|
|
163
|
+
" For-profit organisations should contact Anthony L. Spek, a.l.spek@uu.nl for a license."
|
|
147
164
|
" "
|
|
148
165
|
)
|
|
149
166
|
self.set_checkcif_output_font(self.ui.CheckcifPlaintextEdit)
|
|
@@ -161,7 +178,7 @@ class AppWindow(QMainWindow):
|
|
|
161
178
|
# self.set_font_sizes()
|
|
162
179
|
|
|
163
180
|
def load_fontsize_from_settings(self):
|
|
164
|
-
fontsize = self.settings.load_value_of_key('global_font_size')
|
|
181
|
+
fontsize = cast(int, self.settings.load_value_of_key('global_font_size'))
|
|
165
182
|
if fontsize is not None and fontsize >= 8:
|
|
166
183
|
self.set_global_font(fontsize)
|
|
167
184
|
self.ui.textSizeSpinBox.setValue(fontsize)
|
|
@@ -428,6 +445,23 @@ class AppWindow(QMainWindow):
|
|
|
428
445
|
self.ui.ImportAllTemplatesPushButton.clicked.connect(self.import_all_templates)
|
|
429
446
|
self.ui.searchMainTableLineEdit.textChanged.connect(self.ui.cif_main_table.search)
|
|
430
447
|
self.ui.textSizeSpinBox.valueChanged.connect(self.set_global_font)
|
|
448
|
+
# video:
|
|
449
|
+
self.ui.SelectVideo_PushButton.clicked.connect(lambda x: self._select_crystal_video())
|
|
450
|
+
self.ui.videoRightToolButton.clicked.connect(self.video.next)
|
|
451
|
+
self.ui.videoLeftToolButton.clicked.connect(self.video.previous)
|
|
452
|
+
self.ui.setVideoPicturePushButton.clicked.connect(self.set_video_image_for_report)
|
|
453
|
+
|
|
454
|
+
def set_video_image_for_report(self):
|
|
455
|
+
image_filename = self.cif.finalcif_file_prefixed(prefix='', suffix='_video-finalcif.png')
|
|
456
|
+
self.video.save_image(image_filename)
|
|
457
|
+
self.options.video_image = image_filename
|
|
458
|
+
|
|
459
|
+
def _select_crystal_video(self, video_file: Path | None = None) -> None:
|
|
460
|
+
if video_file is None:
|
|
461
|
+
video_file = Path(video_file_open_dialog(parent=self, last_dir=self.get_last_workdir()))
|
|
462
|
+
if video_file is not None and video_file.is_file() and video_file.exists():
|
|
463
|
+
self.ui.videoLineEdit.setText(str(video_file.resolve()))
|
|
464
|
+
self.video.load_file(video_file)
|
|
431
465
|
|
|
432
466
|
@property
|
|
433
467
|
def finalcif_changes_filename(self):
|
|
@@ -437,8 +471,7 @@ class AppWindow(QMainWindow):
|
|
|
437
471
|
self.make_loops_tables()
|
|
438
472
|
self.ui.MainStackedWidget.go_to_loops_page()
|
|
439
473
|
|
|
440
|
-
def export_all_templates(self, filename: Path | None = None):
|
|
441
|
-
import pickle
|
|
474
|
+
def export_all_templates(self, filename: Path | None = None) -> None:
|
|
442
475
|
if not filename:
|
|
443
476
|
filename, _ = compat.getsavefilename(parent=self,
|
|
444
477
|
basedir=str(Path(self.get_last_workdir()).joinpath(
|
|
@@ -461,7 +494,7 @@ class AppWindow(QMainWindow):
|
|
|
461
494
|
except pickle.PickleError as e:
|
|
462
495
|
self.status_bar.show_message(f'Saving templates failed: {e!s}')
|
|
463
496
|
|
|
464
|
-
def import_all_templates(self, filename: Path | None = None):
|
|
497
|
+
def import_all_templates(self, filename: Path | None = None) -> None:
|
|
465
498
|
import pickle
|
|
466
499
|
if not filename:
|
|
467
500
|
filename, _ = compat.getopenfilename(parent=self,
|
|
@@ -737,7 +770,7 @@ class AppWindow(QMainWindow):
|
|
|
737
770
|
if self.options.track_changes and self.changes_answer == QMessageBox.StandardButton.Yes:
|
|
738
771
|
self.delete_key_from_changes_cif(key)
|
|
739
772
|
|
|
740
|
-
def delete_key_from_changes_cif(self, key):
|
|
773
|
+
def delete_key_from_changes_cif(self, key: str) -> None:
|
|
741
774
|
changes_cif = self.get_changes_cif(self.finalcif_changes_filename)
|
|
742
775
|
del changes_cif[key]
|
|
743
776
|
if changes_cif.is_empty():
|
|
@@ -921,7 +954,10 @@ class AppWindow(QMainWindow):
|
|
|
921
954
|
url = QtCore.QUrl.fromLocalFile(str(self.htmlfile.resolve()))
|
|
922
955
|
self.ui.MainStackedWidget.go_to_checkcif_page()
|
|
923
956
|
self.ui.CheckCIFResultsTabWidget.setCurrentIndex(1) # Index 1 is html page
|
|
924
|
-
|
|
957
|
+
try:
|
|
958
|
+
self.checkcif_browser.setHtml(self.htmlfile.resolve().read_text('utf-8', 'ignore'))
|
|
959
|
+
except FileNotFoundError:
|
|
960
|
+
print(f'{self.htmlfile} not found')
|
|
925
961
|
self.ui.ResponsesTabWidget.setCurrentIndex(0)
|
|
926
962
|
threading.Thread(target=self._display_structure_factor_report, args=(parser,)).start()
|
|
927
963
|
# The picture file linked in the html file:
|
|
@@ -1030,7 +1066,6 @@ class AppWindow(QMainWindow):
|
|
|
1030
1066
|
def _pdf_checkcif_finished(self) -> None:
|
|
1031
1067
|
self.ui.CheckcifPDFOnlineButton.setEnabled(True)
|
|
1032
1068
|
self.ui.CheckcifHTMLOnlineButton.setEnabled(True)
|
|
1033
|
-
self.ckf.show_pdf_report()
|
|
1034
1069
|
|
|
1035
1070
|
def do_pdf_checkcif(self) -> None:
|
|
1036
1071
|
"""
|
|
@@ -1109,12 +1144,7 @@ class AppWindow(QMainWindow):
|
|
|
1109
1144
|
|
|
1110
1145
|
def set_checkcif_output_font(self, ccpe: 'QPlainTextEdit') -> None:
|
|
1111
1146
|
doc = ccpe.document()
|
|
1112
|
-
|
|
1113
|
-
font.setFamily("Courier New")
|
|
1114
|
-
font.setStyleHint(QtGui.QFont.StyleHint.Monospace)
|
|
1115
|
-
# app.processEvents()
|
|
1116
|
-
# font.setPointSize(14)
|
|
1117
|
-
doc.setDefaultFont(font)
|
|
1147
|
+
doc.setDefaultFont(self.fixfont)
|
|
1118
1148
|
|
|
1119
1149
|
def load_recent_file(self, file_index: int) -> None:
|
|
1120
1150
|
"""
|
|
@@ -1138,10 +1168,12 @@ class AppWindow(QMainWindow):
|
|
|
1138
1168
|
caption='Open a Report Picture')
|
|
1139
1169
|
self.set_report_picture_path(filename)
|
|
1140
1170
|
|
|
1141
|
-
def set_report_picture_path(self, filename: str):
|
|
1171
|
+
def set_report_picture_path(self, filename: str) -> None:
|
|
1172
|
+
if not filename:
|
|
1173
|
+
return None
|
|
1142
1174
|
with suppress(Exception):
|
|
1143
1175
|
self.report_picture_path = Path(filename)
|
|
1144
|
-
if self.report_picture_path.exists() and self.report_picture_path.is_file():
|
|
1176
|
+
if self.report_picture_path and self.report_picture_path.exists() and self.report_picture_path.is_file():
|
|
1145
1177
|
with suppress(Exception):
|
|
1146
1178
|
self.set_picture_button_icon()
|
|
1147
1179
|
|
|
@@ -1181,9 +1213,9 @@ class AppWindow(QMainWindow):
|
|
|
1181
1213
|
self.cif.picometer = self.options.use_picometers
|
|
1182
1214
|
# The picture after the header:
|
|
1183
1215
|
if self.report_picture_path:
|
|
1184
|
-
|
|
1216
|
+
self.options.structure_figure = self.report_picture_path
|
|
1185
1217
|
else:
|
|
1186
|
-
|
|
1218
|
+
self.options.structure_figure = self.cif.finalcif_file.with_suffix('.gif')
|
|
1187
1219
|
try:
|
|
1188
1220
|
print('Report with templates')
|
|
1189
1221
|
template_path = Path(self.get_checked_templates_list_text())
|
|
@@ -1191,7 +1223,6 @@ class AppWindow(QMainWindow):
|
|
|
1191
1223
|
if template_path.suffix in ('.docx',):
|
|
1192
1224
|
t = TemplatedReport(format=ReportFormat.RICHTEXT, options=self.options, cif=self.cif)
|
|
1193
1225
|
ok = t.make_templated_docx_report(output_filename=str(report_filename),
|
|
1194
|
-
picfile=picfile,
|
|
1195
1226
|
template_path=Path(self.get_checked_templates_list_text()))
|
|
1196
1227
|
if self.cif.is_multi_cif and self.cif.doc[0].name != 'global':
|
|
1197
1228
|
make_multi_tables(cif=self.cif, output_filename=str(multi_table_document))
|
|
@@ -1199,7 +1230,6 @@ class AppWindow(QMainWindow):
|
|
|
1199
1230
|
t = TemplatedReport(format=ReportFormat.HTML, options=self.options, cif=self.cif)
|
|
1200
1231
|
report_filename = report_filename.with_suffix('.html')
|
|
1201
1232
|
ok = t.make_templated_html_report(output_filename=str(report_filename),
|
|
1202
|
-
picfile=picfile,
|
|
1203
1233
|
template_path=template_path.parent,
|
|
1204
1234
|
template_file=template_path.name)
|
|
1205
1235
|
if not ok:
|
|
@@ -1213,10 +1243,11 @@ class AppWindow(QMainWindow):
|
|
|
1213
1243
|
return
|
|
1214
1244
|
except PermissionError:
|
|
1215
1245
|
if DEBUG:
|
|
1246
|
+
print('dbg> Unable to open report or CIF file')
|
|
1216
1247
|
raise
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1248
|
+
show_general_warning(self,
|
|
1249
|
+
f'The document {report_filename.name} could not be opened to '
|
|
1250
|
+
f'write the report.\nIs the file already opened?')
|
|
1220
1251
|
return
|
|
1221
1252
|
if not self.running_inside_unit_test:
|
|
1222
1253
|
self.open_report_document(report_filename, multi_table_document)
|
|
@@ -1266,6 +1297,13 @@ class AppWindow(QMainWindow):
|
|
|
1266
1297
|
recent.remove(filename)
|
|
1267
1298
|
# file has to be str not Path():
|
|
1268
1299
|
recent.insert(0, filename)
|
|
1300
|
+
for file in recent:
|
|
1301
|
+
try:
|
|
1302
|
+
if not file or not os.path.exists(file):
|
|
1303
|
+
recent.remove(file)
|
|
1304
|
+
continue
|
|
1305
|
+
except Exception:
|
|
1306
|
+
pass
|
|
1269
1307
|
recent = recent[:10]
|
|
1270
1308
|
self.settings.settings.setValue('recent_files', recent)
|
|
1271
1309
|
|
|
@@ -1423,15 +1461,13 @@ class AppWindow(QMainWindow):
|
|
|
1423
1461
|
self.ui.MainStackedWidget.go_to_cif_text_page()
|
|
1424
1462
|
final_textedit = self.ui.FinalCifFilePlainTextEdit
|
|
1425
1463
|
doc = final_textedit.document()
|
|
1426
|
-
font = doc.defaultFont()
|
|
1427
|
-
font.setFamily("Courier New")
|
|
1428
|
-
font.setStyleHint(QtGui.QFont.StyleHint.Monospace)
|
|
1429
1464
|
# increases the pont size every time a bit more :)
|
|
1430
1465
|
# size = font.pointSize()
|
|
1431
1466
|
# font.setPointSize(14)
|
|
1432
|
-
doc.setDefaultFont(
|
|
1467
|
+
doc.setDefaultFont(self.fixfont)
|
|
1433
1468
|
final_textedit.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap)
|
|
1434
1469
|
final_textedit.setPlainText(self.cif.finalcif_file.read_text(encoding='utf-8', errors='ignore'))
|
|
1470
|
+
QtCore.QTimer().singleShot(0, lambda: final_textedit.highlighter.setDocument(doc))
|
|
1435
1471
|
|
|
1436
1472
|
def import_additional_cif(self, filename: str):
|
|
1437
1473
|
"""
|
|
@@ -1496,12 +1532,12 @@ class AppWindow(QMainWindow):
|
|
|
1496
1532
|
self.set_path_display_in_file_selector(str(filepath))
|
|
1497
1533
|
try:
|
|
1498
1534
|
if not self.able_to_open(filepath):
|
|
1499
|
-
return
|
|
1535
|
+
return None
|
|
1500
1536
|
except (OSError, IndexError):
|
|
1501
1537
|
print('Something failed during cif file opening...')
|
|
1502
1538
|
if DEBUG:
|
|
1503
1539
|
raise
|
|
1504
|
-
return
|
|
1540
|
+
return None
|
|
1505
1541
|
not_ok = None
|
|
1506
1542
|
try:
|
|
1507
1543
|
e = None
|
|
@@ -1515,14 +1551,14 @@ class AppWindow(QMainWindow):
|
|
|
1515
1551
|
if not_ok:
|
|
1516
1552
|
unable_to_open_message(self, filepath, not_ok)
|
|
1517
1553
|
return None
|
|
1518
|
-
if not self.cif.is_valid_structure_cif
|
|
1554
|
+
if not self.cif.is_valid_structure_cif:
|
|
1519
1555
|
show_general_warning(self, "The CIF file you are about to open contains no structure.\n\n"
|
|
1520
1556
|
"Use the Import button below to import metadata.")
|
|
1521
1557
|
return None
|
|
1522
1558
|
if not self.cif.chars_ok:
|
|
1523
1559
|
self.warn_about_bad_cif()
|
|
1524
1560
|
# Do this only when sure we can load the file:
|
|
1525
|
-
self.save_current_recent_files_list(filepath)
|
|
1561
|
+
QtCore.QTimer.singleShot(0, lambda: self.save_current_recent_files_list(filepath))
|
|
1526
1562
|
self._load_block(block, load_changes=load_changes)
|
|
1527
1563
|
self.add_data_names_to_combobox()
|
|
1528
1564
|
self.ui.datanameComboBox.setCurrentIndex(block)
|
|
@@ -1531,9 +1567,18 @@ class AppWindow(QMainWindow):
|
|
|
1531
1567
|
if self.cif.is_multi_cif:
|
|
1532
1568
|
self._flash_block_combobox()
|
|
1533
1569
|
self.cif.set_order_keys(self.ui.cifOrderWidget.order_keys)
|
|
1570
|
+
QtCore.QTimer().singleShot(0, self._find_video)
|
|
1534
1571
|
# Enable to find widgets without parent:
|
|
1535
1572
|
# QtCore.QTimer(self).singleShot(1000, self.find_widgets_without_parent)
|
|
1536
1573
|
|
|
1574
|
+
def _find_video(self) -> None:
|
|
1575
|
+
self.video.reset()
|
|
1576
|
+
self.ui.videoLineEdit.setText('')
|
|
1577
|
+
path = self.cif.fileobj.parent.parent
|
|
1578
|
+
videos = list(path.glob('*.vzs'))
|
|
1579
|
+
if videos:
|
|
1580
|
+
self._select_crystal_video(videos[0])
|
|
1581
|
+
|
|
1537
1582
|
def find_widgets_without_parent(self) -> None:
|
|
1538
1583
|
print('Finding parents...')
|
|
1539
1584
|
all_widgets = app.allWidgets()
|
|
@@ -2038,11 +2083,7 @@ class AppWindow(QMainWindow):
|
|
|
2038
2083
|
self.ui.LoopsTabWidget.addTab(textedit, 'SHELX res file')
|
|
2039
2084
|
textedit.setPlainText(self.cif.res_file_data[1:-1])
|
|
2040
2085
|
doc = textedit.document()
|
|
2041
|
-
|
|
2042
|
-
font.setFamily("Courier New")
|
|
2043
|
-
font.setStyleHint(QtGui.QFont.StyleHint.Monospace)
|
|
2044
|
-
# font.setPointSize(14)
|
|
2045
|
-
doc.setDefaultFont(font)
|
|
2086
|
+
doc.setDefaultFont(self.fixfont)
|
|
2046
2087
|
textedit.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap)
|
|
2047
2088
|
textedit.setReadOnly(True)
|
|
2048
2089
|
|
|
@@ -105,6 +105,11 @@ additional_keywords = {
|
|
|
105
105
|
'The O(CH2CH3)2 solvent molecule (42 electrons) disordred around '
|
|
106
106
|
'an inverstion center was treated by SQUEEZE. '
|
|
107
107
|
'<br><p><h4>Type:</h4> string </p>\n',
|
|
108
|
+
'_exptl_bruker_absorpt_correction_T_ratio': '<pre><h2>_exptl_bruker_absorpt_correction_T_ratio</h2>'
|
|
109
|
+
'SADABS (and other scaling programs) can only determine the RATIO of '
|
|
110
|
+
'absorpt_correction_Tmin/Tmax, so this value determined by SHELXL is used to '
|
|
111
|
+
'scale the transmission values from SADABS.</pre>'
|
|
112
|
+
'<br><p><h4>Type:</h4> number (float) </p>\n',
|
|
108
113
|
}
|
|
109
114
|
|
|
110
115
|
cif_all_dict = {}
|
|
@@ -15,6 +15,7 @@ from pathlib import Path
|
|
|
15
15
|
|
|
16
16
|
import requests
|
|
17
17
|
from qtpy.QtCore import QThread, Signal
|
|
18
|
+
from requests import Response
|
|
18
19
|
from requests.exceptions import MissingSchema
|
|
19
20
|
|
|
20
21
|
from finalcif.cif.cif_file_io import CifContainer
|
|
@@ -91,8 +92,10 @@ class CheckCif(QThread):
|
|
|
91
92
|
with suppress(Exception):
|
|
92
93
|
# parameter missing_ok=True is only available after 3.8
|
|
93
94
|
Path('finalcif_checkcif_tmp.cif').unlink()
|
|
95
|
+
if self.pdf:
|
|
96
|
+
self.finished.connect(self._open_pdf_result)
|
|
94
97
|
|
|
95
|
-
def _do_the_server_request(self, headers: dict, temp_cif: bytes):
|
|
98
|
+
def _do_the_server_request(self, headers: dict, temp_cif: bytes) -> Response | None:
|
|
96
99
|
req = None
|
|
97
100
|
try:
|
|
98
101
|
req = requests.post(self.checkcif_url, files={'file': temp_cif}, data=headers, timeout=900)
|
|
@@ -14,6 +14,10 @@ special_keys = ['_iucr_refine_instructions_details',
|
|
|
14
14
|
'_refln_F_squared_sigma',
|
|
15
15
|
'_refln_F_calc',
|
|
16
16
|
'_refln_F_squared_calc',
|
|
17
|
+
|
|
18
|
+
'_shelx_include_file_name',
|
|
19
|
+
'_shelx_include_file',
|
|
20
|
+
'_shelx_include_file_checksum',
|
|
17
21
|
]
|
|
18
22
|
|
|
19
23
|
order = [
|
|
@@ -349,19 +353,19 @@ order = [
|
|
|
349
353
|
'_geom_details',
|
|
350
354
|
'_geom_special_details',
|
|
351
355
|
|
|
352
|
-
'_bruker_diffrn_runs_wavelength',
|
|
353
|
-
'_bruker_diffrn_runs_temperature',
|
|
354
|
-
'_bruker_diffrn_runs_current',
|
|
355
|
-
'_bruker_diffrn_runs_voltage',
|
|
356
|
-
'_bruker_diffrn_runs_images',
|
|
357
|
-
'_bruker_diffrn_runs_time',
|
|
358
|
-
'_bruker_diffrn_runs_width',
|
|
359
356
|
'_bruker_diffrn_runs_axis',
|
|
360
|
-
'_bruker_diffrn_runs_chi',
|
|
361
|
-
'_bruker_diffrn_runs_phi',
|
|
362
|
-
'_bruker_diffrn_runs_omega',
|
|
363
|
-
'_bruker_diffrn_runs_theta',
|
|
364
357
|
'_bruker_diffrn_runs_distance',
|
|
358
|
+
'_bruker_diffrn_runs_theta',
|
|
359
|
+
'_bruker_diffrn_runs_omega',
|
|
360
|
+
'_bruker_diffrn_runs_phi',
|
|
361
|
+
'_bruker_diffrn_runs_chi',
|
|
362
|
+
'_bruker_diffrn_runs_width',
|
|
363
|
+
'_bruker_diffrn_runs_images',
|
|
364
|
+
'_bruker_diffrn_runs_time',
|
|
365
|
+
'_bruker_diffrn_runs_wavelength',
|
|
366
|
+
'_bruker_diffrn_runs_voltage',
|
|
367
|
+
'_bruker_diffrn_runs_current',
|
|
368
|
+
'_bruker_diffrn_runs_temperature',
|
|
365
369
|
]
|
|
366
370
|
|
|
367
371
|
|
|
@@ -113,8 +113,6 @@ class Ui_CifOrderForm(object):
|
|
|
113
113
|
|
|
114
114
|
|
|
115
115
|
self.retranslateUi(CifOrderForm)
|
|
116
|
-
|
|
117
|
-
QMetaObject.connectSlotsByName(CifOrderForm)
|
|
118
116
|
# setupUi
|
|
119
117
|
|
|
120
118
|
def retranslateUi(self, CifOrderForm):
|
|
@@ -134,7 +132,7 @@ class Ui_CifOrderForm(object):
|
|
|
134
132
|
self.restoreDefaultPushButton.setText(QCoreApplication.translate("CifOrderForm", u"Restore default order", None))
|
|
135
133
|
self.deleteKeyPushButton.setText(QCoreApplication.translate("CifOrderForm", u"Delete selected key", None))
|
|
136
134
|
___qtablewidgetitem = self.cifOrderTableWidget.horizontalHeaderItem(0)
|
|
137
|
-
___qtablewidgetitem.setText(QCoreApplication.translate("CifOrderForm", u"CIF key", None))
|
|
135
|
+
___qtablewidgetitem.setText(QCoreApplication.translate("CifOrderForm", u"CIF key", None))
|
|
138
136
|
self.helpTextLabel.setText(QCoreApplication.translate("CifOrderForm", u"Order of CIF keys in the output file. Enabled means they will be forced to remain in the output CIF.", None))
|
|
139
137
|
# retranslateUi
|
|
140
138
|
|
|
@@ -381,7 +381,7 @@ class AuthorLoops:
|
|
|
381
381
|
authors.append(author_data)
|
|
382
382
|
return authors
|
|
383
383
|
|
|
384
|
-
def import_raw_data(self, authors_data: list[Author]):
|
|
384
|
+
def import_raw_data(self, authors_data: list[Author]) -> None:
|
|
385
385
|
"""
|
|
386
386
|
Import all authors from an external file"""
|
|
387
387
|
for author in authors_data:
|
|
@@ -391,7 +391,7 @@ class AuthorLoops:
|
|
|
391
391
|
def authors_list(self) -> list[str]:
|
|
392
392
|
return self.settings.list_saved_items(property='authors_list')
|
|
393
393
|
|
|
394
|
-
def contact_author_checked(self, checked: bool):
|
|
394
|
+
def contact_author_checked(self, checked: bool) -> None:
|
|
395
395
|
"""
|
|
396
396
|
:parameter checked: state of the ContactAuthorCheckBox
|
|
397
397
|
"""
|
|
@@ -55,7 +55,7 @@ class Properties(QtCore.QObject):
|
|
|
55
55
|
self.app.ui.ExportPropertyButton.clicked.connect(self.export_property_template)
|
|
56
56
|
self.app.ui.cifKeywordLineEdit.textChanged.connect(self.check_for_duplicates)
|
|
57
57
|
|
|
58
|
-
def check_for_duplicates(self):
|
|
58
|
+
def check_for_duplicates(self) -> None:
|
|
59
59
|
key = self.app.ui.cifKeywordLineEdit.text()
|
|
60
60
|
props = self.export_raw_data()
|
|
61
61
|
keys = [x['cif_key'] for x in props]
|
|
@@ -66,13 +66,12 @@ class Properties(QtCore.QObject):
|
|
|
66
66
|
self.lb.setText(f'key {key} already exists')
|
|
67
67
|
self.lb.move(self.app.ui.cifKeywordLineEdit.mapToGlobal(QtCore.QPoint(15, 25)))
|
|
68
68
|
self.lb.show()
|
|
69
|
-
|
|
69
|
+
QtCore.QTimer().singleShot(5000, self.hide_label)
|
|
70
70
|
else:
|
|
71
71
|
self.app.ui.SavePropertiesButton.setEnabled(True)
|
|
72
72
|
self.lb.hide()
|
|
73
73
|
|
|
74
|
-
def hide_label(self):
|
|
75
|
-
time.sleep(5)
|
|
74
|
+
def hide_label(self) -> None:
|
|
76
75
|
self.lb.hide()
|
|
77
76
|
|
|
78
77
|
def show_properties(self) -> None:
|
|
@@ -276,9 +275,9 @@ class Properties(QtCore.QObject):
|
|
|
276
275
|
return properties_list
|
|
277
276
|
|
|
278
277
|
def import_raw_data(self, properties_list: list[dict]) -> None:
|
|
279
|
-
for
|
|
280
|
-
self.settings.save_settings_list(property='property', name=
|
|
281
|
-
items=[
|
|
278
|
+
for property in properties_list:
|
|
279
|
+
self.settings.save_settings_list(property='property', name=property.get("name"),
|
|
280
|
+
items=[property.get('cif_key'), property.get('data')])
|
|
282
281
|
self.show_properties()
|
|
283
282
|
|
|
284
283
|
@staticmethod
|
|
@@ -3,11 +3,10 @@ import os
|
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
+
from finalcif import VERSION
|
|
6
7
|
from qtpy import QtCore, compat
|
|
7
8
|
from qtpy.QtWidgets import QMessageBox, QMainWindow, QVBoxLayout, QTextEdit, QPushButton, QFrame
|
|
8
9
|
|
|
9
|
-
from finalcif import VERSION
|
|
10
|
-
|
|
11
10
|
|
|
12
11
|
def do_update_program(version) -> None:
|
|
13
12
|
updater_exe = str(Path(__file__).parent.parent.parent.joinpath('update.exe'))
|
|
@@ -229,6 +228,17 @@ def cif_file_save_dialog(filename: str, parent=None) -> str:
|
|
|
229
228
|
return filename
|
|
230
229
|
|
|
231
230
|
|
|
231
|
+
def video_file_open_dialog(parent: object = None, filter: str = "Video file (*.vzs; *.jpg)", last_dir='', options=None) -> str:
|
|
232
|
+
filename, _ = compat.getopenfilename(parent=parent,
|
|
233
|
+
caption='Open a crystal video file',
|
|
234
|
+
basedir=last_dir,
|
|
235
|
+
filters=filter,
|
|
236
|
+
selectedfilter=filter,
|
|
237
|
+
options=options
|
|
238
|
+
)
|
|
239
|
+
return filename
|
|
240
|
+
|
|
241
|
+
|
|
232
242
|
if __name__ == '__main__':
|
|
233
243
|
from qtpy import QtWidgets
|
|
234
244
|
from qtpy.QtWidgets import QApplication
|
|
@@ -6,6 +6,8 @@ from qtpy.QtCore import QRect, QSize
|
|
|
6
6
|
from qtpy.QtGui import QColor, QPainter, QTextFormat
|
|
7
7
|
from qtpy.QtWidgets import QWidget, QPlainTextEdit, QTextEdit
|
|
8
8
|
|
|
9
|
+
from finalcif.gui import syntax_highlighter
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
class QLineNumberArea(QWidget):
|
|
11
13
|
def __init__(self, parent: QCodeEditor):
|
|
@@ -22,6 +24,7 @@ class QLineNumberArea(QWidget):
|
|
|
22
24
|
class QCodeEditor(QPlainTextEdit):
|
|
23
25
|
def __init__(self, parent=None):
|
|
24
26
|
super().__init__(parent)
|
|
27
|
+
self.highlighter = syntax_highlighter.CIFSyntaxHighlighter(self)
|
|
25
28
|
self.lineNumberArea = QLineNumberArea(self)
|
|
26
29
|
self.blockCountChanged.connect(self.update_line_number_area_width)
|
|
27
30
|
self.updateRequest.connect(self.update_line_number_area)
|
|
@@ -80,9 +83,7 @@ class QCodeEditor(QPlainTextEdit):
|
|
|
80
83
|
if block.isVisible() and (bottom >= event.rect().top()):
|
|
81
84
|
number = f'{block_number + 1} '
|
|
82
85
|
painter.setPen(QtCore.Qt.GlobalColor.black)
|
|
83
|
-
font =
|
|
84
|
-
font.setFamily("Courier")
|
|
85
|
-
font.setStyleHint(QtGui.QFont.StyleHint.Monospace)
|
|
86
|
+
font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.SystemFont.FixedFont)
|
|
86
87
|
painter.setFont(font)
|
|
87
88
|
painter.drawText(0, top, self.lineNumberArea.width(), height,
|
|
88
89
|
QtCore.Qt.AlignmentFlag.AlignRight, number)
|
|
@@ -95,13 +96,19 @@ class QCodeEditor(QPlainTextEdit):
|
|
|
95
96
|
|
|
96
97
|
if __name__ == '__main__':
|
|
97
98
|
from qtpy.QtWidgets import QApplication
|
|
98
|
-
|
|
99
|
+
import gemmi
|
|
99
100
|
app = QApplication.instance()
|
|
100
101
|
if app is None:
|
|
101
102
|
app = QApplication([])
|
|
102
103
|
import sys
|
|
103
104
|
|
|
104
105
|
codeEditor = QCodeEditor()
|
|
105
|
-
codeEditor.
|
|
106
|
+
codeEditor.setMinimumSize(800, 600)
|
|
107
|
+
font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.SystemFont.FixedFont)
|
|
108
|
+
codeEditor.setFont(font)
|
|
109
|
+
options = gemmi.cif.WriteOptions(gemmi.cif.Style(gemmi.cif.Style.Indent35))
|
|
110
|
+
ciftext = gemmi.cif.read('test-data/DK_Zucker2_0m.cif').sole_block().as_string(options)
|
|
111
|
+
codeEditor.setPlainText(ciftext)
|
|
112
|
+
codeEditor.highlighter.setDocument(codeEditor.document())
|
|
106
113
|
codeEditor.show()
|
|
107
114
|
sys.exit(app.exec())
|