finalcif 154__tar.gz → 156__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.
Files changed (168) hide show
  1. {finalcif-154 → finalcif-156}/.gitignore +8 -0
  2. {finalcif-154 → finalcif-156}/PKG-INFO +1 -1
  3. finalcif-156/finalcif/__init__.py +2 -0
  4. {finalcif-154 → finalcif-156}/finalcif/appwindow.py +66 -22
  5. {finalcif-154 → finalcif-156}/finalcif/cif/all_cif_dicts.py +5 -0
  6. {finalcif-154 → finalcif-156}/finalcif/cif/checkcif/checkcif.py +4 -1
  7. {finalcif-154 → finalcif-156}/finalcif/cif/cif_order.py +15 -11
  8. {finalcif-154 → finalcif-156}/finalcif/ciforder/order_ui.py +0 -2
  9. {finalcif-154 → finalcif-156}/finalcif/equip_property/author_loop_templates.py +2 -2
  10. {finalcif-154 → finalcif-156}/finalcif/equip_property/properties.py +3 -3
  11. {finalcif-154 → finalcif-156}/finalcif/gui/dialogs.py +12 -2
  12. {finalcif-154 → finalcif-156}/finalcif/gui/finalcif_gui_ui.py +380 -279
  13. {finalcif-154 → finalcif-156}/finalcif/gui/finalcif_gui_ui.ui +361 -185
  14. {finalcif-154 → finalcif-156}/finalcif/gui/import_selector_ui.py +0 -2
  15. {finalcif-154 → finalcif-156}/finalcif/gui/loop_creator_ui.py +0 -2
  16. {finalcif-154 → finalcif-156}/finalcif/gui/loops.py +0 -1
  17. {finalcif-154 → finalcif-156}/finalcif/gui/new_key_dialog_ui.py +0 -2
  18. {finalcif-154 → finalcif-156}/finalcif/gui/text_templates_ui.py +0 -2
  19. finalcif-156/finalcif/gui/vzs_viewer.py +182 -0
  20. {finalcif-154 → finalcif-156}/finalcif/report/gui/mainwindow.py +0 -2
  21. {finalcif-154 → finalcif-156}/finalcif/report/references.py +1 -1
  22. {finalcif-154 → finalcif-156}/finalcif/report/templated_report.py +30 -36
  23. {finalcif-154 → finalcif-156}/finalcif/template/report.tmpl +45 -21
  24. finalcif-156/finalcif/template/report_default.docx +0 -0
  25. {finalcif-154 → finalcif-156}/finalcif/tools/misc.py +1 -0
  26. {finalcif-154 → finalcif-156}/finalcif/tools/options.py +12 -4
  27. {finalcif-154 → finalcif-156}/finalcif/tools/shred.py +1 -2
  28. {finalcif-154 → finalcif-156}/platon/README.txt +11 -0
  29. finalcif-156/pylock.toml +892 -0
  30. {finalcif-154 → finalcif-156}/pyproject.toml +12 -2
  31. {finalcif-154 → finalcif-156}/uv.lock +88 -1
  32. finalcif-154/finalcif/__init__.py +0 -2
  33. finalcif-154/finalcif/template/report_default.docx +0 -0
  34. {finalcif-154 → finalcif-156}/.gitattributes +0 -0
  35. {finalcif-154 → finalcif-156}/.python-version +0 -0
  36. {finalcif-154 → finalcif-156}/.ruff.toml +0 -0
  37. {finalcif-154 → finalcif-156}/.run/Make Documentation MAC.run.xml +0 -0
  38. {finalcif-154 → finalcif-156}/.run/compile_ui_files.run.xml +0 -0
  39. {finalcif-154 → finalcif-156}/.run/make documentation Windows.run.xml +0 -0
  40. {finalcif-154 → finalcif-156}/CODE_OF_CONDUCT.md +0 -0
  41. {finalcif-154 → finalcif-156}/CONTRIBUTING.md +0 -0
  42. {finalcif-154 → finalcif-156}/Finalcif_installer_win.spec +0 -0
  43. {finalcif-154 → finalcif-156}/Finalcif_linux_onefile.spec +0 -0
  44. {finalcif-154 → finalcif-156}/Finalcif_mac.spec +0 -0
  45. {finalcif-154 → finalcif-156}/Hydrogen_solution_type.cif +0 -0
  46. {finalcif-154 → finalcif-156}/LICENSE +0 -0
  47. {finalcif-154 → finalcif-156}/README.md +0 -0
  48. {finalcif-154 → finalcif-156}/finalcif/app_path.py +0 -0
  49. {finalcif-154 → finalcif-156}/finalcif/cif/__init__.py +0 -0
  50. {finalcif-154 → finalcif-156}/finalcif/cif/atoms.py +0 -0
  51. {finalcif-154 → finalcif-156}/finalcif/cif/checkcif/__init__.py +0 -0
  52. {finalcif-154 → finalcif-156}/finalcif/cif/cif_dict_foo.py +0 -0
  53. {finalcif-154 → finalcif-156}/finalcif/cif/cif_file_io.py +0 -0
  54. {finalcif-154 → finalcif-156}/finalcif/cif/cod/__init__.py +0 -0
  55. {finalcif-154 → finalcif-156}/finalcif/cif/cod/deposit.py +0 -0
  56. {finalcif-154 → finalcif-156}/finalcif/cif/cod/deposit_check.py +0 -0
  57. {finalcif-154 → finalcif-156}/finalcif/cif/cod/deposition_list.py +0 -0
  58. {finalcif-154 → finalcif-156}/finalcif/cif/cod/doi.py +0 -0
  59. {finalcif-154 → finalcif-156}/finalcif/cif/cod/upload.py +0 -0
  60. {finalcif-154 → finalcif-156}/finalcif/cif/cod/website_parser.py +0 -0
  61. {finalcif-154 → finalcif-156}/finalcif/cif/core_dict.py +0 -0
  62. {finalcif-154 → finalcif-156}/finalcif/cif/hkl.py +0 -0
  63. {finalcif-154 → finalcif-156}/finalcif/cif/modulation_dict.py +0 -0
  64. {finalcif-154 → finalcif-156}/finalcif/cif/powder_dict.py +0 -0
  65. {finalcif-154 → finalcif-156}/finalcif/cif/reference.py +0 -0
  66. {finalcif-154 → finalcif-156}/finalcif/cif/restraints_dict.py +0 -0
  67. {finalcif-154 → finalcif-156}/finalcif/cif/text.py +0 -0
  68. {finalcif-154 → finalcif-156}/finalcif/cif/twin_dict.py +0 -0
  69. {finalcif-154 → finalcif-156}/finalcif/ciforder/__init__.py +0 -0
  70. {finalcif-154 → finalcif-156}/finalcif/ciforder/order.py +0 -0
  71. {finalcif-154 → finalcif-156}/finalcif/ciforder/order_ui.ui +0 -0
  72. {finalcif-154 → finalcif-156}/finalcif/datafiles/__init__.py +0 -0
  73. {finalcif-154 → finalcif-156}/finalcif/datafiles/bruker_data.py +0 -0
  74. {finalcif-154 → finalcif-156}/finalcif/datafiles/bruker_frame.py +0 -0
  75. {finalcif-154 → finalcif-156}/finalcif/datafiles/ccdc_mail.py +0 -0
  76. {finalcif-154 → finalcif-156}/finalcif/datafiles/data.py +0 -0
  77. {finalcif-154 → finalcif-156}/finalcif/datafiles/p4p_reader.py +0 -0
  78. {finalcif-154 → finalcif-156}/finalcif/datafiles/sadabs.py +0 -0
  79. {finalcif-154 → finalcif-156}/finalcif/datafiles/saint.py +0 -0
  80. {finalcif-154 → finalcif-156}/finalcif/datafiles/shelx_lst.py +0 -0
  81. {finalcif-154 → finalcif-156}/finalcif/datafiles/utils.py +0 -0
  82. {finalcif-154 → finalcif-156}/finalcif/displaymol/__init__.py +0 -0
  83. {finalcif-154 → finalcif-156}/finalcif/displaymol/molecule2D.py +0 -0
  84. {finalcif-154 → finalcif-156}/finalcif/displaymol/sdm.py +0 -0
  85. {finalcif-154 → finalcif-156}/finalcif/displaymol/vtk_molecule.py +0 -0
  86. {finalcif-154 → finalcif-156}/finalcif/equip_property/__init__.py +0 -0
  87. {finalcif-154 → finalcif-156}/finalcif/equip_property/equipment.py +0 -0
  88. {finalcif-154 → finalcif-156}/finalcif/equip_property/tools.py +0 -0
  89. {finalcif-154 → finalcif-156}/finalcif/finalcif_start.py +0 -0
  90. {finalcif-154 → finalcif-156}/finalcif/gui/__init__.py +0 -0
  91. {finalcif-154 → finalcif-156}/finalcif/gui/block_combobox.py +0 -0
  92. {finalcif-154 → finalcif-156}/finalcif/gui/combobox.py +0 -0
  93. {finalcif-154 → finalcif-156}/finalcif/gui/custom_classes.py +0 -0
  94. {finalcif-154 → finalcif-156}/finalcif/gui/edit_button.py +0 -0
  95. {finalcif-154 → finalcif-156}/finalcif/gui/equipmenttable.py +0 -0
  96. {finalcif-154 → finalcif-156}/finalcif/gui/file_editor.py +0 -0
  97. {finalcif-154 → finalcif-156}/finalcif/gui/import_selector.py +0 -0
  98. {finalcif-154 → finalcif-156}/finalcif/gui/import_selector_ui.ui +0 -0
  99. {finalcif-154 → finalcif-156}/finalcif/gui/loop_creator.py +0 -0
  100. {finalcif-154 → finalcif-156}/finalcif/gui/loop_creator_ui.ui +0 -0
  101. {finalcif-154 → finalcif-156}/finalcif/gui/mainstackwidget.py +0 -0
  102. {finalcif-154 → finalcif-156}/finalcif/gui/mixins.py +0 -0
  103. {finalcif-154 → finalcif-156}/finalcif/gui/new_key_dialog.py +0 -0
  104. {finalcif-154 → finalcif-156}/finalcif/gui/new_key_dialog_ui.ui +0 -0
  105. {finalcif-154 → finalcif-156}/finalcif/gui/plaintextedit.py +0 -0
  106. {finalcif-154 → finalcif-156}/finalcif/gui/playground.py +0 -0
  107. {finalcif-154 → finalcif-156}/finalcif/gui/propertytable.py +0 -0
  108. {finalcif-154 → finalcif-156}/finalcif/gui/spell_check_edit.py +0 -0
  109. {finalcif-154 → finalcif-156}/finalcif/gui/text_templates_ui.ui +0 -0
  110. {finalcif-154 → finalcif-156}/finalcif/gui/text_value_editor.py +0 -0
  111. {finalcif-154 → finalcif-156}/finalcif/gui/validators.py +0 -0
  112. {finalcif-154 → finalcif-156}/finalcif/gui/vrf_classes.py +0 -0
  113. {finalcif-154 → finalcif-156}/finalcif/icon/__init__.py +0 -0
  114. {finalcif-154 → finalcif-156}/finalcif/icon/finalcif.png +0 -0
  115. {finalcif-154 → finalcif-156}/finalcif/icon/finalcif2.ico +0 -0
  116. {finalcif-154 → finalcif-156}/finalcif/icon/finalcif2.png +0 -0
  117. {finalcif-154 → finalcif-156}/finalcif/icon/multitable.ico +0 -0
  118. {finalcif-154 → finalcif-156}/finalcif/icon/multitable.png +0 -0
  119. {finalcif-154 → finalcif-156}/finalcif/icon/multitable.xcf +0 -0
  120. {finalcif-154 → finalcif-156}/finalcif/report/__init__.py +0 -0
  121. {finalcif-154 → finalcif-156}/finalcif/report/archive_report.py +0 -0
  122. {finalcif-154 → finalcif-156}/finalcif/report/gui/__init__.py +0 -0
  123. {finalcif-154 → finalcif-156}/finalcif/report/gui/mainwindow.ui +0 -0
  124. {finalcif-154 → finalcif-156}/finalcif/report/mtools.py +0 -0
  125. {finalcif-154 → finalcif-156}/finalcif/report/report_text.py +0 -0
  126. {finalcif-154 → finalcif-156}/finalcif/report/symm.py +0 -0
  127. {finalcif-154 → finalcif-156}/finalcif/report/tables.py +0 -0
  128. {finalcif-154 → finalcif-156}/finalcif/template/__init__.py +0 -0
  129. {finalcif-154 → finalcif-156}/finalcif/template/bootstrap/bootstrap.min.css +0 -0
  130. {finalcif-154 → finalcif-156}/finalcif/template/machines/D8_VENTURE.cif +0 -0
  131. {finalcif-154 → finalcif-156}/finalcif/template/mathml2omml.xsl +0 -0
  132. {finalcif-154 → finalcif-156}/finalcif/template/template1.docx +0 -0
  133. {finalcif-154 → finalcif-156}/finalcif/template/template_for_multitable.docx +0 -0
  134. {finalcif-154 → finalcif-156}/finalcif/template/template_text.docx +0 -0
  135. {finalcif-154 → finalcif-156}/finalcif/template/template_without_text.docx +0 -0
  136. {finalcif-154 → finalcif-156}/finalcif/template/templates.py +0 -0
  137. {finalcif-154 → finalcif-156}/finalcif/template/xsl/convert.py +0 -0
  138. {finalcif-154 → finalcif-156}/finalcif/template/xsl/xmltohtml.xsl +0 -0
  139. {finalcif-154 → finalcif-156}/finalcif/tools/__init__.py +0 -0
  140. {finalcif-154 → finalcif-156}/finalcif/tools/chemparse.py +0 -0
  141. {finalcif-154 → finalcif-156}/finalcif/tools/download.py +0 -0
  142. {finalcif-154 → finalcif-156}/finalcif/tools/dsrmath.py +0 -0
  143. {finalcif-154 → finalcif-156}/finalcif/tools/platon.py +0 -0
  144. {finalcif-154 → finalcif-156}/finalcif/tools/pupdate.py +0 -0
  145. {finalcif-154 → finalcif-156}/finalcif/tools/settings.py +0 -0
  146. {finalcif-154 → finalcif-156}/finalcif/tools/space_groups.py +0 -0
  147. {finalcif-154 → finalcif-156}/finalcif/tools/spgr_format.py +0 -0
  148. {finalcif-154 → finalcif-156}/finalcif/tools/statusbar.py +0 -0
  149. {finalcif-154 → finalcif-156}/finalcif/tools/sumformula.py +0 -0
  150. {finalcif-154 → finalcif-156}/finalcif.exe +0 -0
  151. {finalcif-154 → finalcif-156}/install_requirements +0 -0
  152. {finalcif-154 → finalcif-156}/install_requirements.bat +0 -0
  153. {finalcif-154 → finalcif-156}/platon/compile_platon.bat +0 -0
  154. {finalcif-154 → finalcif-156}/platon/platon_special.exe +0 -0
  155. {finalcif-154 → finalcif-156}/platon/platon_special.f +0 -0
  156. {finalcif-154 → finalcif-156}/requirements.txt +0 -0
  157. {finalcif-154 → finalcif-156}/requirements_devel.txt +0 -0
  158. {finalcif-154 → finalcif-156}/requirements_doku.txt +0 -0
  159. {finalcif-154 → finalcif-156}/run_finalcif +0 -0
  160. {finalcif-154 → finalcif-156}/run_finalcif.bat +0 -0
  161. {finalcif-154 → finalcif-156}/screenshots/finalcif_checkcif.png +0 -0
  162. {finalcif-154 → finalcif-156}/screenshots/finalcif_details.png +0 -0
  163. {finalcif-154 → finalcif-156}/screenshots/finalcif_loops.png +0 -0
  164. {finalcif-154 → finalcif-156}/screenshots/finalcif_loops2.png +0 -0
  165. {finalcif-154 → finalcif-156}/screenshots/finalcif_main.png +0 -0
  166. {finalcif-154 → finalcif-156}/screenshots/finalcif_report.png +0 -0
  167. {finalcif-154 → finalcif-156}/screenshots/finalcif_responses.png +0 -0
  168. {finalcif-154 → finalcif-156}/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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: finalcif
3
- Version: 154
3
+ Version: 156
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
@@ -0,0 +1,2 @@
1
+
2
+ VERSION = 156
@@ -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
@@ -124,6 +132,9 @@ class AppWindow(QMainWindow):
124
132
  self.ui.TemplatesStackedWidget.setCurrentIndex(0)
125
133
  self.ui.MainStackedWidget.got_to_main_page()
126
134
  self.set_initial_button_states()
135
+ self.video = VZSImageViewer(self)
136
+ self.ui.picturesTabWidget.setCurrentIndex(0)
137
+ self.ui.video_vLayout.addWidget(self.video)
127
138
  if file:
128
139
  self.load_cif_file(file)
129
140
  self.load_recent_cifs_list()
@@ -143,7 +154,9 @@ class AppWindow(QMainWindow):
143
154
  " Spek, A.L. (2020). Acta Cryst. E76, 1-11.\n"
144
155
  " \n"
145
156
  " \n"
146
- " - Recent versions of PLATON may be obtained from: https://platonsoft.nl/xraysoft\n"
157
+ " - Recent versions of PLATON may be obtained from: https://platonsoft.nl/xraysoft\n\n"
158
+ " PLATON is free of charge for Academics.\n"
159
+ " For-profit organisations should contact Anthony L. Spek, a.l.spek@uu.nl for a license."
147
160
  " "
148
161
  )
149
162
  self.set_checkcif_output_font(self.ui.CheckcifPlaintextEdit)
@@ -161,7 +174,7 @@ class AppWindow(QMainWindow):
161
174
  # self.set_font_sizes()
162
175
 
163
176
  def load_fontsize_from_settings(self):
164
- fontsize = self.settings.load_value_of_key('global_font_size')
177
+ fontsize = cast(int, self.settings.load_value_of_key('global_font_size'))
165
178
  if fontsize is not None and fontsize >= 8:
166
179
  self.set_global_font(fontsize)
167
180
  self.ui.textSizeSpinBox.setValue(fontsize)
@@ -428,6 +441,23 @@ class AppWindow(QMainWindow):
428
441
  self.ui.ImportAllTemplatesPushButton.clicked.connect(self.import_all_templates)
429
442
  self.ui.searchMainTableLineEdit.textChanged.connect(self.ui.cif_main_table.search)
430
443
  self.ui.textSizeSpinBox.valueChanged.connect(self.set_global_font)
444
+ # video:
445
+ self.ui.SelectVideo_PushButton.clicked.connect(lambda x: self._select_crystal_video())
446
+ self.ui.videoRightToolButton.clicked.connect(self.video.next)
447
+ self.ui.videoLeftToolButton.clicked.connect(self.video.previous)
448
+ self.ui.setVideoPicturePushButton.clicked.connect(self.set_video_image_for_report)
449
+
450
+ def set_video_image_for_report(self):
451
+ image_filename = self.cif.finalcif_file_prefixed(prefix='', suffix='_video-finalcif.png')
452
+ self.video.save_image(image_filename)
453
+ self.options.video_image = image_filename
454
+
455
+ def _select_crystal_video(self, video_file: Path | None = None) -> None:
456
+ if video_file is None:
457
+ video_file = Path(video_file_open_dialog(parent=self, last_dir=self.get_last_workdir()))
458
+ if video_file is not None and video_file.is_file() and video_file.exists():
459
+ self.ui.videoLineEdit.setText(str(video_file.resolve()))
460
+ self.video.load_file(video_file)
431
461
 
432
462
  @property
433
463
  def finalcif_changes_filename(self):
@@ -437,8 +467,7 @@ class AppWindow(QMainWindow):
437
467
  self.make_loops_tables()
438
468
  self.ui.MainStackedWidget.go_to_loops_page()
439
469
 
440
- def export_all_templates(self, filename: Path | None = None):
441
- import pickle
470
+ def export_all_templates(self, filename: Path | None = None) -> None:
442
471
  if not filename:
443
472
  filename, _ = compat.getsavefilename(parent=self,
444
473
  basedir=str(Path(self.get_last_workdir()).joinpath(
@@ -461,7 +490,7 @@ class AppWindow(QMainWindow):
461
490
  except pickle.PickleError as e:
462
491
  self.status_bar.show_message(f'Saving templates failed: {e!s}')
463
492
 
464
- def import_all_templates(self, filename: Path | None = None):
493
+ def import_all_templates(self, filename: Path | None = None) -> None:
465
494
  import pickle
466
495
  if not filename:
467
496
  filename, _ = compat.getopenfilename(parent=self,
@@ -737,7 +766,7 @@ class AppWindow(QMainWindow):
737
766
  if self.options.track_changes and self.changes_answer == QMessageBox.StandardButton.Yes:
738
767
  self.delete_key_from_changes_cif(key)
739
768
 
740
- def delete_key_from_changes_cif(self, key):
769
+ def delete_key_from_changes_cif(self, key: str) -> None:
741
770
  changes_cif = self.get_changes_cif(self.finalcif_changes_filename)
742
771
  del changes_cif[key]
743
772
  if changes_cif.is_empty():
@@ -921,7 +950,10 @@ class AppWindow(QMainWindow):
921
950
  url = QtCore.QUrl.fromLocalFile(str(self.htmlfile.resolve()))
922
951
  self.ui.MainStackedWidget.go_to_checkcif_page()
923
952
  self.ui.CheckCIFResultsTabWidget.setCurrentIndex(1) # Index 1 is html page
924
- self.checkcif_browser.load(url)
953
+ try:
954
+ self.checkcif_browser.setHtml(self.htmlfile.resolve().read_text('utf-8', 'ignore'))
955
+ except FileNotFoundError:
956
+ print(f'{self.htmlfile} not found')
925
957
  self.ui.ResponsesTabWidget.setCurrentIndex(0)
926
958
  threading.Thread(target=self._display_structure_factor_report, args=(parser,)).start()
927
959
  # The picture file linked in the html file:
@@ -979,7 +1011,8 @@ class AppWindow(QMainWindow):
979
1011
  self.ckf = CheckCif(parent=self, cif=self.cif, outfile=self.htmlfile,
980
1012
  hkl_upload=(not self.ui.structfactCheckBox.isChecked()), pdf=False,
981
1013
  url=self.options.checkcif_url,
982
- full_iucr=self.ui.fullIucrCheckBox.isChecked())
1014
+ full_iucr=self.ui.fullIucrCheckBox.isChecked(),
1015
+ check_duplicates=self.ui.checkDuplicatesCheckBox.isChecked())
983
1016
  self.ckf.progress.connect(self._ckf_progress)
984
1017
  self.ckf.failed.connect(self._checkcif_failed)
985
1018
  self.ckf.finished.connect(self._checkcif_finished)
@@ -1052,7 +1085,8 @@ class AppWindow(QMainWindow):
1052
1085
  self.ckf = CheckCif(parent=self, cif=self.cif, outfile=htmlfile,
1053
1086
  hkl_upload=(not self.ui.structfactCheckBox.isChecked()),
1054
1087
  pdf=True, url=self.options.checkcif_url,
1055
- full_iucr=self.ui.fullIucrCheckBox.isChecked())
1088
+ full_iucr=self.ui.fullIucrCheckBox.isChecked(),
1089
+ check_duplicates=self.ui.checkDuplicatesCheckBox.isChecked())
1056
1090
  self.ckf.failed.connect(self._checkcif_failed)
1057
1091
  # noinspection PyUnresolvedReferences
1058
1092
  self.ckf.finished.connect(self._pdf_checkcif_finished)
@@ -1136,10 +1170,12 @@ class AppWindow(QMainWindow):
1136
1170
  caption='Open a Report Picture')
1137
1171
  self.set_report_picture_path(filename)
1138
1172
 
1139
- def set_report_picture_path(self, filename: str):
1173
+ def set_report_picture_path(self, filename: str) -> None:
1174
+ if not filename:
1175
+ return None
1140
1176
  with suppress(Exception):
1141
1177
  self.report_picture_path = Path(filename)
1142
- if self.report_picture_path.exists() and self.report_picture_path.is_file():
1178
+ if self.report_picture_path and self.report_picture_path.exists() and self.report_picture_path.is_file():
1143
1179
  with suppress(Exception):
1144
1180
  self.set_picture_button_icon()
1145
1181
 
@@ -1179,9 +1215,9 @@ class AppWindow(QMainWindow):
1179
1215
  self.cif.picometer = self.options.use_picometers
1180
1216
  # The picture after the header:
1181
1217
  if self.report_picture_path:
1182
- picfile = self.report_picture_path
1218
+ self.options.structure_figure = self.report_picture_path
1183
1219
  else:
1184
- picfile = self.cif.finalcif_file.with_suffix('.gif')
1220
+ self.options.structure_figure = self.cif.finalcif_file.with_suffix('.gif')
1185
1221
  try:
1186
1222
  print('Report with templates')
1187
1223
  template_path = Path(self.get_checked_templates_list_text())
@@ -1189,7 +1225,6 @@ class AppWindow(QMainWindow):
1189
1225
  if template_path.suffix in ('.docx',):
1190
1226
  t = TemplatedReport(format=ReportFormat.RICHTEXT, options=self.options, cif=self.cif)
1191
1227
  ok = t.make_templated_docx_report(output_filename=str(report_filename),
1192
- picfile=picfile,
1193
1228
  template_path=Path(self.get_checked_templates_list_text()))
1194
1229
  if self.cif.is_multi_cif and self.cif.doc[0].name != 'global':
1195
1230
  make_multi_tables(cif=self.cif, output_filename=str(multi_table_document))
@@ -1197,7 +1232,6 @@ class AppWindow(QMainWindow):
1197
1232
  t = TemplatedReport(format=ReportFormat.HTML, options=self.options, cif=self.cif)
1198
1233
  report_filename = report_filename.with_suffix('.html')
1199
1234
  ok = t.make_templated_html_report(output_filename=str(report_filename),
1200
- picfile=picfile,
1201
1235
  template_path=template_path.parent,
1202
1236
  template_file=template_path.name)
1203
1237
  if not ok:
@@ -1211,10 +1245,11 @@ class AppWindow(QMainWindow):
1211
1245
  return
1212
1246
  except PermissionError:
1213
1247
  if DEBUG:
1248
+ print('dbg> Unable to open report or CIF file')
1214
1249
  raise
1215
- print('Unable to open cif file')
1216
- show_general_warning(self, f'The report document {report_filename.name} could not be opened.\n'
1217
- 'Is the file already opened?')
1250
+ show_general_warning(self,
1251
+ f'The document {report_filename.name} could not be opened to '
1252
+ f'write the report.\nIs the file already opened?')
1218
1253
  return
1219
1254
  if not self.running_inside_unit_test:
1220
1255
  self.open_report_document(report_filename, multi_table_document)
@@ -1494,12 +1529,12 @@ class AppWindow(QMainWindow):
1494
1529
  self.set_path_display_in_file_selector(str(filepath))
1495
1530
  try:
1496
1531
  if not self.able_to_open(filepath):
1497
- return
1532
+ return None
1498
1533
  except (OSError, IndexError):
1499
1534
  print('Something failed during cif file opening...')
1500
1535
  if DEBUG:
1501
1536
  raise
1502
- return
1537
+ return None
1503
1538
  not_ok = None
1504
1539
  try:
1505
1540
  e = None
@@ -1513,7 +1548,7 @@ class AppWindow(QMainWindow):
1513
1548
  if not_ok:
1514
1549
  unable_to_open_message(self, filepath, not_ok)
1515
1550
  return None
1516
- if not self.cif.is_valid_structure_cif and not self.cif.doc.find_block('global'):
1551
+ if not self.cif.is_valid_structure_cif:
1517
1552
  show_general_warning(self, "The CIF file you are about to open contains no structure.\n\n"
1518
1553
  "Use the Import button below to import metadata.")
1519
1554
  return None
@@ -1529,9 +1564,18 @@ class AppWindow(QMainWindow):
1529
1564
  if self.cif.is_multi_cif:
1530
1565
  self._flash_block_combobox()
1531
1566
  self.cif.set_order_keys(self.ui.cifOrderWidget.order_keys)
1567
+ QtCore.QTimer().singleShot(0, self._find_video)
1532
1568
  # Enable to find widgets without parent:
1533
1569
  # QtCore.QTimer(self).singleShot(1000, self.find_widgets_without_parent)
1534
1570
 
1571
+ def _find_video(self) -> None:
1572
+ self.video.reset()
1573
+ self.ui.videoLineEdit.setText('')
1574
+ path = self.cif.fileobj.parent.parent
1575
+ videos = list(path.glob('*.vzs'))
1576
+ if videos:
1577
+ self._select_crystal_video(videos[0])
1578
+
1535
1579
  def find_widgets_without_parent(self) -> None:
1536
1580
  print('Finding parents...')
1537
1581
  all_widgets = app.allWidgets()
@@ -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 = {}
@@ -25,7 +25,7 @@ class CheckCif(QThread):
25
25
  failed = Signal(str)
26
26
 
27
27
  def __init__(self, parent, cif: CifContainer, outfile: Path, hkl_upload: bool = True,
28
- pdf: bool = False, url: str = '', full_iucr: bool = False):
28
+ pdf: bool = False, url: str = '', full_iucr: bool = False, check_duplicates: bool = True):
29
29
  # hkl == False means no hkl upload
30
30
  super().__init__(parent=parent)
31
31
  self.hkl_upload = hkl_upload
@@ -34,6 +34,7 @@ class CheckCif(QThread):
34
34
  self.pdf = pdf
35
35
  self.checkcif_url = url
36
36
  self.full_iucr = full_iucr
37
+ self.check_duplicates = check_duplicates
37
38
 
38
39
  def _html_check(self) -> None:
39
40
  if self.hkl_upload:
@@ -63,11 +64,13 @@ class CheckCif(QThread):
63
64
  validation_type = 'checkcif_with_hkl'
64
65
  vrf = self.get_vrf()
65
66
  headers = {
67
+ "from_index": "from_index",
66
68
  "runtype" : "symmonly",
67
69
  "referer" : "checkcif_server",
68
70
  "outputtype": 'PDF' if self.pdf else 'HTML',
69
71
  "validtype" : validation_type,
70
72
  "valout" : vrf,
73
+ "duplic" : "duplicyes" if self.check_duplicates else "duplicno",
71
74
  }
72
75
  t1 = time.perf_counter()
73
76
  self.progress.emit('Report request sent. Please wait...')
@@ -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):
@@ -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
  """
@@ -276,9 +276,9 @@ class Properties(QtCore.QObject):
276
276
  return properties_list
277
277
 
278
278
  def import_raw_data(self, properties_list: list[dict]) -> None:
279
- for prop in properties_list:
280
- self.settings.save_settings_list(property='property', name=prop.get("name"),
281
- items=[prop.get('cif_key'), prop.get('data')])
279
+ for property in properties_list:
280
+ self.settings.save_settings_list(property='property', name=property.get("name"),
281
+ items=[property.get('cif_key'), property.get('data')])
282
282
  self.show_properties()
283
283
 
284
284
  @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