not1mm 25.4.10__tar.gz → 25.4.11.3__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 (192) hide show
  1. {not1mm-25.4.10 → not1mm-25.4.11.3}/PKG-INFO +8 -1
  2. {not1mm-25.4.10 → not1mm-25.4.11.3}/README.md +7 -0
  3. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/__main__.py +26 -10
  4. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/new_contest.ui +15 -0
  5. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/cwinterface.py +20 -2
  6. not1mm-25.4.11.3/not1mm/lib/version.py +3 -0
  7. not1mm-25.4.11.3/not1mm/plugins/ari_40_80.py +482 -0
  8. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_ww_cw.py +3 -1
  9. not1mm-25.4.11.3/not1mm/plugins/sac_cw.py +668 -0
  10. not1mm-25.4.11.3/not1mm/plugins/sac_ssb.py +668 -0
  11. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm.egg-info/PKG-INFO +8 -1
  12. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm.egg-info/SOURCES.txt +3 -0
  13. {not1mm-25.4.10 → not1mm-25.4.11.3}/pyproject.toml +1 -1
  14. not1mm-25.4.10/not1mm/lib/version.py +0 -4
  15. {not1mm-25.4.10 → not1mm-25.4.11.3}/LICENSE +0 -0
  16. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/__init__.py +0 -0
  17. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/bandmap.py +0 -0
  18. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/checkwindow.py +0 -0
  19. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/JetBrainsMono-ExtraLight.ttf +0 -0
  20. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/MASTER.SCP +0 -0
  21. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/about.ui +0 -0
  22. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/alpha bravo charlie delta.txt +0 -0
  23. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/bandmap.ui +0 -0
  24. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/check.png +0 -0
  25. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/checkwindow.ui +0 -0
  26. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/configuration.ui +0 -0
  27. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/contests.sql +0 -0
  28. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/cty.json +0 -0
  29. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/cwmacros.txt +0 -0
  30. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/donors.html +0 -0
  31. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/editcontact.ui +0 -0
  32. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/editmacro.ui +0 -0
  33. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/greendot.png +0 -0
  34. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/k6gte-not1mm.desktop +0 -0
  35. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/k6gte.not1mm-128.png +0 -0
  36. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/k6gte.not1mm-32.png +0 -0
  37. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/k6gte.not1mm-64.png +0 -0
  38. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/logwindow.ui +0 -0
  39. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/logwindowx.ui +0 -0
  40. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/main.ui +0 -0
  41. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/not1mm.html +0 -0
  42. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/opon.ui +0 -0
  43. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/0.wav +0 -0
  44. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/1.wav +0 -0
  45. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/2.wav +0 -0
  46. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/3.wav +0 -0
  47. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/4.wav +0 -0
  48. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/5.wav +0 -0
  49. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/6.wav +0 -0
  50. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/7.wav +0 -0
  51. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/73.wav +0 -0
  52. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/8.wav +0 -0
  53. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/9.wav +0 -0
  54. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/a.wav +0 -0
  55. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/again.wav +0 -0
  56. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/b.wav +0 -0
  57. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/c.wav +0 -0
  58. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/contest.wav +0 -0
  59. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/cq.wav +0 -0
  60. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/cq2.wav +0 -0
  61. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/d.wav +0 -0
  62. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/e.wav +0 -0
  63. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/f.wav +0 -0
  64. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/g.wav +0 -0
  65. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/h.wav +0 -0
  66. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/i.wav +0 -0
  67. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/j.wav +0 -0
  68. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/k.wav +0 -0
  69. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/k6gte.wav +0 -0
  70. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/l.wav +0 -0
  71. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/m.wav +0 -0
  72. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/mynumber.wav +0 -0
  73. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/n.wav +0 -0
  74. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/nil.wav +0 -0
  75. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/o.wav +0 -0
  76. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/p.wav +0 -0
  77. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/q.wav +0 -0
  78. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/r.wav +0 -0
  79. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/roger.wav +0 -0
  80. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/s.wav +0 -0
  81. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/space.wav +0 -0
  82. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/t.wav +0 -0
  83. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/thankyou.wav +0 -0
  84. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
  85. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/u.wav +0 -0
  86. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/v.wav +0 -0
  87. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/w.wav +0 -0
  88. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/x.wav +0 -0
  89. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/y.wav +0 -0
  90. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/yourcall.wav +0 -0
  91. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/phonetics/z.wav +0 -0
  92. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/pickcontest.ui +0 -0
  93. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/radio_green.png +0 -0
  94. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/radio_grey.png +0 -0
  95. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/radio_red.png +0 -0
  96. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/ratewindow.ui +0 -0
  97. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/reddot.png +0 -0
  98. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/rttymacros.txt +0 -0
  99. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/settings.ui +0 -0
  100. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/splash.png +0 -0
  101. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/ssbmacros.txt +0 -0
  102. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/statistics.ui +0 -0
  103. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/data/vfo.ui +0 -0
  104. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/fsutils.py +0 -0
  105. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/__init__.py +0 -0
  106. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/about.py +0 -0
  107. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/cat_interface.py +0 -0
  108. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/database.py +0 -0
  109. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/edit_contact.py +0 -0
  110. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/edit_macro.py +0 -0
  111. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/edit_opon.py +0 -0
  112. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/edit_station.py +0 -0
  113. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/fldigi_sendstring.py +0 -0
  114. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/ft8_watcher.py +0 -0
  115. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/ham_utility.py +0 -0
  116. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/lookup.py +0 -0
  117. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/multicast.py +0 -0
  118. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/n1mm.py +0 -0
  119. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/new_contest.py +0 -0
  120. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/plugin_common.py +0 -0
  121. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/select_contest.py +0 -0
  122. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/settings.py +0 -0
  123. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/super_check_partial.py +0 -0
  124. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lib/versiontest.py +0 -0
  125. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/logwindow.py +0 -0
  126. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/lookupservice.py +0 -0
  127. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/10_10_fall_cw.py +0 -0
  128. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/10_10_spring_cw.py +0 -0
  129. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/10_10_summer_phone.py +0 -0
  130. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/10_10_winter_phone.py +0 -0
  131. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/__init__.py +0 -0
  132. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_10m.py +0 -0
  133. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_160m.py +0 -0
  134. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_dx_cw.py +0 -0
  135. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_dx_ssb.py +0 -0
  136. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_field_day.py +0 -0
  137. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_rtty_ru.py +0 -0
  138. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_ss_cw.py +0 -0
  139. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_ss_phone.py +0 -0
  140. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_vhf_jan.py +0 -0
  141. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_vhf_jun.py +0 -0
  142. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/arrl_vhf_sep.py +0 -0
  143. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/canada_day.py +0 -0
  144. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_160_cw.py +0 -0
  145. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_160_ssb.py +0 -0
  146. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_wpx_cw.py +0 -0
  147. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_wpx_rtty.py +0 -0
  148. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_wpx_ssb.py +0 -0
  149. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_ww_rtty.py +0 -0
  150. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cq_ww_ssb.py +0 -0
  151. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/cwt.py +0 -0
  152. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/darc_vhf.py +0 -0
  153. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/darc_xmas.py +0 -0
  154. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/ea_majistad_cw.py +0 -0
  155. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/ea_majistad_ssb.py +0 -0
  156. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/ea_rtty.py +0 -0
  157. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/general_logging.py +0 -0
  158. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/helvetia.py +0 -0
  159. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/iaru_fieldday_r1_cw.py +0 -0
  160. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/iaru_fieldday_r1_ssb.py +0 -0
  161. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/iaru_hf.py +0 -0
  162. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/icwc_mst.py +0 -0
  163. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/jidx_cw.py +0 -0
  164. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/jidx_ph.py +0 -0
  165. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/k1usn_sst.py +0 -0
  166. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/labre_rs_digi.py +0 -0
  167. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/lz-dx.py +0 -0
  168. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/naqp_cw.py +0 -0
  169. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/naqp_rtty.py +0 -0
  170. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/naqp_ssb.py +0 -0
  171. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/phone_weekly_test.py +0 -0
  172. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/raem.py +0 -0
  173. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/randomgram.py +0 -0
  174. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/ref_cw.py +0 -0
  175. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/ref_ssb.py +0 -0
  176. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/spdx.py +0 -0
  177. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/stew_perry_topband.py +0 -0
  178. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/ukeidx.py +0 -0
  179. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/weekly_rtty.py +0 -0
  180. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/plugins/winter_field_day.py +0 -0
  181. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/radio.py +0 -0
  182. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/ratewindow.py +0 -0
  183. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/rtc_service.py +0 -0
  184. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/statistics.py +0 -0
  185. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/test.py +0 -0
  186. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/vfo.py +0 -0
  187. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm/voice_keying.py +0 -0
  188. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm.egg-info/dependency_links.txt +0 -0
  189. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm.egg-info/entry_points.txt +0 -0
  190. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm.egg-info/requires.txt +0 -0
  191. {not1mm-25.4.10 → not1mm-25.4.11.3}/not1mm.egg-info/top_level.txt +0 -0
  192. {not1mm-25.4.10 → not1mm-25.4.11.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: not1mm
3
- Version: 25.4.10
3
+ Version: 25.4.11.3
4
4
  Summary: NOT1MM Logger
5
5
  Author-email: Michael Bridak <michael.bridak@gmail.com>
6
6
  License: GPL-3.0-or-later
@@ -242,6 +242,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
242
242
  - RandomGram
243
243
  - RAC Canada Day
244
244
  - REF CW, SSB
245
+ - SAC CW, SSB
245
246
  - SPDX
246
247
  - Stew Perry Topband
247
248
  - UK/EI DX
@@ -250,6 +251,11 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
250
251
 
251
252
  ## Recent Changes
252
253
 
254
+ - [25-4-11-3] Fixed issue with winkeyer not sending multiple macros in ESM mode.
255
+ - [25-4-11-2] Fixed a crash.
256
+ - [25-4-11-1] Add clear buffer to winkeyer interface to stop sending.
257
+ - [25-4-11] Add Scandinavian Activity Contest
258
+ - [25-4-10-1] Add ARI 40/80 contest. Add Auto CQ visual indicator. Add CTRL-R to toggle Run state.
253
259
  - [25-4-10] Add Auto CQ visual indicator.
254
260
  - [25-4-9] Added UKEI DX
255
261
  - [25-4-8] Remove focus from statistics table widget.
@@ -778,6 +784,7 @@ is this has happened, since the gridsquare will replace the word "Regional".
778
784
  | [SPACE] | When in the callsign field, will move the input to the first field needed for the exchange. |
779
785
  | [Enter] | Submits the fields to the log. Unless ESM is enabled. |
780
786
  | [F1-F12] | Send (CW/RTTY/Voice) macros. |
787
+ | [CTRL-R] | Toggle between Run and S&P modes. |
781
788
  | [CTRL-S] | Spot Callsign to the cluster. |
782
789
  | [CTRL-M] | Mark Callsign to the bandmap window to work later. |
783
790
  | [CTRL-G] | Tune to a spot matching partial text in the callsign entry field (CAT Required). |
@@ -210,6 +210,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
210
210
  - RandomGram
211
211
  - RAC Canada Day
212
212
  - REF CW, SSB
213
+ - SAC CW, SSB
213
214
  - SPDX
214
215
  - Stew Perry Topband
215
216
  - UK/EI DX
@@ -218,6 +219,11 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
218
219
 
219
220
  ## Recent Changes
220
221
 
222
+ - [25-4-11-3] Fixed issue with winkeyer not sending multiple macros in ESM mode.
223
+ - [25-4-11-2] Fixed a crash.
224
+ - [25-4-11-1] Add clear buffer to winkeyer interface to stop sending.
225
+ - [25-4-11] Add Scandinavian Activity Contest
226
+ - [25-4-10-1] Add ARI 40/80 contest. Add Auto CQ visual indicator. Add CTRL-R to toggle Run state.
221
227
  - [25-4-10] Add Auto CQ visual indicator.
222
228
  - [25-4-9] Added UKEI DX
223
229
  - [25-4-8] Remove focus from statistics table widget.
@@ -746,6 +752,7 @@ is this has happened, since the gridsquare will replace the word "Regional".
746
752
  | [SPACE] | When in the callsign field, will move the input to the first field needed for the exchange. |
747
753
  | [Enter] | Submits the fields to the log. Unless ESM is enabled. |
748
754
  | [F1-F12] | Send (CW/RTTY/Voice) macros. |
755
+ | [CTRL-R] | Toggle between Run and S&P modes. |
749
756
  | [CTRL-S] | Spot Callsign to the cluster. |
750
757
  | [CTRL-M] | Mark Callsign to the bandmap window to work later. |
751
758
  | [CTRL-G] | Tune to a spot matching partial text in the callsign entry field (CAT Required). |
@@ -1853,6 +1853,7 @@ class MainWindow(QtWidgets.QMainWindow):
1853
1853
  "[CTRL-SHIFT-K] Open CW text input field.\n"
1854
1854
  "[CTRL-=]\tLog the contact without sending the ESM macros.\n"
1855
1855
  "[CTRL-W]\tClears the input fields of any text.\n"
1856
+ "[CTRL-R]\tToggle the Run state.\n"
1856
1857
  )
1857
1858
 
1858
1859
  def filepicker(self, action: str) -> str:
@@ -2110,6 +2111,9 @@ class MainWindow(QtWidgets.QMainWindow):
2110
2111
  if self.cw.servertype == 1:
2111
2112
  self.cw.sendcw("\x1b4")
2112
2113
  return
2114
+ if self.cw.servertype == 2:
2115
+ self.cw.winkeyer_stop()
2116
+ return
2113
2117
  if self.rig_control:
2114
2118
  if self.rig_control.online:
2115
2119
  if self.pref.get("cwtype") == 3 and self.rig_control is not None:
@@ -2212,6 +2216,20 @@ class MainWindow(QtWidgets.QMainWindow):
2212
2216
  if self.bandmap_window:
2213
2217
  self.bandmap_window.msg_from_main(cmd)
2214
2218
  return
2219
+ if (
2220
+ event.key() == Qt.Key.Key_R
2221
+ and modifier == Qt.KeyboardModifier.ControlModifier
2222
+ ): # pylint: disable=no-member
2223
+ self.toggle_run_sp()
2224
+ return
2225
+ if (
2226
+ event.key() == Qt.Key.Key_T
2227
+ and modifier == Qt.KeyboardModifier.ControlModifier
2228
+ ): # pylint: disable=no-member
2229
+ if hasattr(self.contest, "add_test_data"):
2230
+ self.contest.add_test_data(self)
2231
+ return
2232
+
2215
2233
  if (
2216
2234
  event.key() == Qt.Key.Key_W
2217
2235
  and modifier == Qt.KeyboardModifier.ControlModifier
@@ -2223,16 +2241,6 @@ class MainWindow(QtWidgets.QMainWindow):
2223
2241
  and modifier != Qt.KeyboardModifier.ControlModifier
2224
2242
  ):
2225
2243
  self.stop_cw()
2226
- # if self.cw is not None:
2227
- # if self.cw.servertype == 1:
2228
- # self.cw.sendcw("\x1b4")
2229
- # return
2230
- # if self.rig_control:
2231
- # if self.rig_control.online:
2232
- # if self.pref.get("cwtype") == 3 and self.rig_control is not None:
2233
- # if self.rig_control.interface == "flrig":
2234
- # self.rig_control.cat.set_flrig_cw_send(False)
2235
- # self.rig_control.cat.set_flrig_cw_send(True)
2236
2244
  if event.key() == Qt.Key.Key_Up:
2237
2245
  cmd = {}
2238
2246
  cmd["cmd"] = "PREVSPOT"
@@ -2971,6 +2979,14 @@ class MainWindow(QtWidgets.QMainWindow):
2971
2979
  return
2972
2980
  self.cw.sendcw(self.process_macro(function_key.toolTip()))
2973
2981
 
2982
+ def toggle_run_sp(self) -> None:
2983
+ """Toggles the radioButton_run and radioButton_sp."""
2984
+ if self.radioButton_run.isChecked():
2985
+ self.radioButton_sp.setChecked(True)
2986
+ else:
2987
+ self.radioButton_run.setChecked(True)
2988
+ self.run_sp_buttons_clicked()
2989
+
2974
2990
  def run_sp_buttons_clicked(self) -> None:
2975
2991
  """
2976
2992
  Handle Run/S&P mode changes.
@@ -212,6 +212,11 @@
212
212
  <string>10 10 WINTER PHONE</string>
213
213
  </property>
214
214
  </item>
215
+ <item>
216
+ <property name="text">
217
+ <string>ARI 40 80</string>
218
+ </property>
219
+ </item>
215
220
  <item>
216
221
  <property name="text">
217
222
  <string>ARRL 10M</string>
@@ -432,6 +437,16 @@
432
437
  <string>REF SSB</string>
433
438
  </property>
434
439
  </item>
440
+ <item>
441
+ <property name="text">
442
+ <string>SAC CW</string>
443
+ </property>
444
+ </item>
445
+ <item>
446
+ <property name="text">
447
+ <string>SAC SSB</string>
448
+ </property>
449
+ </item>
435
450
  <item>
436
451
  <property name="text">
437
452
  <string>SPDX</string>
@@ -66,9 +66,9 @@ class CW:
66
66
  if texttosend:
67
67
  if self.servertype == 2:
68
68
  self._sendcw_xmlrpc(texttosend)
69
- if self.servertype == 1:
69
+ elif self.servertype == 1:
70
70
  self._sendcw_udp(texttosend)
71
- if self.servertype == 3:
71
+ elif self.servertype == 3:
72
72
  self._sendcwcat(texttosend)
73
73
 
74
74
  def _sendcw_xmlrpc(self, texttosend):
@@ -130,3 +130,21 @@ class CW:
130
130
  logger.info(
131
131
  "http://%s:%s, xmlrpc Connection Refused", self.host, self.port
132
132
  )
133
+
134
+ def winkeyer_stop(self):
135
+ """doc"""
136
+ if not self.__check_sane_ip(self.host):
137
+ logger.critical(f"Bad IP: {self.host}")
138
+ return
139
+ with ServerProxy(f"http://{self.host}:{self.port}") as proxy:
140
+ try:
141
+ if "clearbuffer" in self.winkeyer_functions:
142
+ proxy.clearbuffer()
143
+ except Error as exception:
144
+ logger.info(
145
+ "http://%s:%s, xmlrpc error: %s", self.host, self.port, exception
146
+ )
147
+ except ConnectionRefusedError:
148
+ logger.info(
149
+ "http://%s:%s, xmlrpc Connection Refused", self.host, self.port
150
+ )
@@ -0,0 +1,3 @@
1
+ """It's the version"""
2
+
3
+ __version__ = "25.4.11.3"
@@ -0,0 +1,482 @@
1
+ """CQ 160 CW plugin"""
2
+
3
+ # pylint: disable=invalid-name, c-extension-no-member, unused-import, line-too-long
4
+
5
+ import datetime
6
+ import logging
7
+ import platform
8
+
9
+ from pathlib import Path
10
+
11
+ from PyQt6 import QtWidgets
12
+
13
+ from not1mm.lib.plugin_common import gen_adif
14
+ from not1mm.lib.version import __version__
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ EXCHANGE_HINT = "Automobile Code"
19
+
20
+ name = "ARI 40 80"
21
+ cabrillo_name = "40-80"
22
+ mode = "BOTH" # CW SSB BOTH RTTY
23
+
24
+ columns = [
25
+ "YYYY-MM-DD HH:MM:SS",
26
+ "Call",
27
+ "Freq",
28
+ "Mode",
29
+ "Snt",
30
+ "Rcv",
31
+ "Exchange1",
32
+ "PTS",
33
+ ]
34
+
35
+ advance_on_space = [True, True, True, True, True]
36
+
37
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
38
+ dupe_type = 3
39
+
40
+
41
+ def init_contest(self):
42
+ """setup plugin"""
43
+ set_tab_next(self)
44
+ set_tab_prev(self)
45
+ interface(self)
46
+ self.next_field = self.other_2
47
+
48
+
49
+ def interface(self):
50
+ """Setup user interface"""
51
+ self.field1.show()
52
+ self.field2.show()
53
+ self.field3.hide()
54
+ self.field4.show()
55
+ self.snt_label.setText("SNT")
56
+ self.field1.setAccessibleName("RST Sent")
57
+ self.exch_label.setText("Automobile Code")
58
+ self.field4.setAccessibleName("Received Exchange")
59
+
60
+
61
+ def reset_label(self): # pylint: disable=unused-argument
62
+ """reset label after field cleared"""
63
+
64
+
65
+ def set_tab_next(self):
66
+ """Set TAB Advances"""
67
+ self.tab_next = {
68
+ self.callsign: self.sent,
69
+ self.sent: self.receive,
70
+ self.receive: self.other_2,
71
+ self.other_1: self.other_2,
72
+ self.other_2: self.callsign,
73
+ }
74
+
75
+
76
+ def set_tab_prev(self):
77
+ """Set TAB Advances"""
78
+ self.tab_prev = {
79
+ self.callsign: self.other_2,
80
+ self.sent: self.callsign,
81
+ self.receive: self.sent,
82
+ self.other_1: self.receive,
83
+ self.other_2: self.receive,
84
+ }
85
+
86
+
87
+ def set_contact_vars(self):
88
+ """Contest Specific"""
89
+ self.contact["SNT"] = self.sent.text()
90
+ self.contact["RCV"] = self.receive.text()
91
+ self.contact["SentNr"] = self.contest_settings.get("SentExchange", 0)
92
+ self.contact["Exchange1"] = self.other_2.text()
93
+ self.contact["IsMultiplier1"] = 0
94
+
95
+
96
+ def predupe(self): # pylint: disable=unused-argument
97
+ """called after callsign entered"""
98
+
99
+
100
+ def prefill(self):
101
+ """Fill SentNR"""
102
+
103
+
104
+ def points(self) -> int:
105
+ """Calc point"""
106
+
107
+ # a . QSOs/HRDs in CW are worth 3 points;
108
+ # b. QSOs/HRDs in RTTY are worth 2 points;
109
+ # c. QSOs/HRDs in SSB are worth 1 point.
110
+
111
+ if self.contact_is_dupe > 0:
112
+ return 0
113
+
114
+ _mode = self.contact.get("Mode", "")
115
+ if _mode in "SSB, USB, LSB, FM, AM":
116
+ return 1
117
+ if _mode in "RTTY":
118
+ return 2
119
+ if _mode in "CW":
120
+ return 3
121
+ return 0
122
+
123
+
124
+ def show_mults(self):
125
+ """Return display string for mults"""
126
+ query = f"select count(DISTINCT(Exchange1 || ':' || Mode || ':' || Band)) as mult_count from dxlog where ContestNR = {self.pref.get('contest', '1')};"
127
+
128
+ result = self.database.exec_sql(query)
129
+ if result:
130
+ return int(result.get("mult_count", 0))
131
+ return 0
132
+
133
+
134
+ def show_qso(self):
135
+ """Return qso count"""
136
+ result = self.database.fetch_qso_count()
137
+ if result:
138
+ return int(result.get("qsos", 0))
139
+ return 0
140
+
141
+
142
+ def calc_score(self):
143
+ """Return calculated score"""
144
+ result = self.database.fetch_points()
145
+ if result is not None:
146
+ score = result.get("Points", "0")
147
+ if score is None:
148
+ score = "0"
149
+ contest_points = int(score)
150
+ mults = int(show_mults(self))
151
+ return contest_points * mults
152
+ return 0
153
+
154
+
155
+ def adif(self):
156
+ """Call the generate ADIF function"""
157
+ gen_adif(self, cabrillo_name, cabrillo_name)
158
+
159
+
160
+ def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
161
+ """"""
162
+ print(
163
+ line_to_output.encode(file_encoding, errors="ignore").decode(),
164
+ end=ending,
165
+ file=file_descriptor,
166
+ )
167
+
168
+
169
+ def cabrillo(self, file_encoding):
170
+ """Generates Cabrillo file. Maybe."""
171
+ # https://www.cw160.com/cabrillo.htm
172
+ logger.debug("******Cabrillo*****")
173
+ logger.debug("Station: %s", f"{self.station}")
174
+ logger.debug("Contest: %s", f"{self.contest_settings}")
175
+ now = datetime.datetime.now()
176
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
177
+ filename = (
178
+ str(Path.home())
179
+ + "/"
180
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
181
+ )
182
+ logger.debug("%s", filename)
183
+ log = self.database.fetch_all_contacts_asc()
184
+ try:
185
+ with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
186
+ output_cabrillo_line(
187
+ "START-OF-LOG: 3.0",
188
+ "\r\n",
189
+ file_descriptor,
190
+ file_encoding,
191
+ )
192
+ output_cabrillo_line(
193
+ f"CREATED-BY: Not1MM v{__version__}",
194
+ "\r\n",
195
+ file_descriptor,
196
+ file_encoding,
197
+ )
198
+ output_cabrillo_line(
199
+ f"CONTEST: {cabrillo_name}",
200
+ "\r\n",
201
+ file_descriptor,
202
+ file_encoding,
203
+ )
204
+ if self.station.get("Club", ""):
205
+ output_cabrillo_line(
206
+ f"CLUB: {self.station.get('Club', '').upper()}",
207
+ "\r\n",
208
+ file_descriptor,
209
+ file_encoding,
210
+ )
211
+ output_cabrillo_line(
212
+ f"CALLSIGN: {self.station.get('Call','')}",
213
+ "\r\n",
214
+ file_descriptor,
215
+ file_encoding,
216
+ )
217
+ output_cabrillo_line(
218
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
219
+ "\r\n",
220
+ file_descriptor,
221
+ file_encoding,
222
+ )
223
+ output_cabrillo_line(
224
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
225
+ "\r\n",
226
+ file_descriptor,
227
+ file_encoding,
228
+ )
229
+ output_cabrillo_line(
230
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
231
+ "\r\n",
232
+ file_descriptor,
233
+ file_encoding,
234
+ )
235
+ output_cabrillo_line(
236
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
237
+ "\r\n",
238
+ file_descriptor,
239
+ file_encoding,
240
+ )
241
+ mode = self.contest_settings.get("ModeCategory", "")
242
+ if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
243
+ mode = "MIXED"
244
+ output_cabrillo_line(
245
+ f"CATEGORY-MODE: {mode}",
246
+ "\r\n",
247
+ file_descriptor,
248
+ file_encoding,
249
+ )
250
+ output_cabrillo_line(
251
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
252
+ "\r\n",
253
+ file_descriptor,
254
+ file_encoding,
255
+ )
256
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
257
+ output_cabrillo_line(
258
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
259
+ "\r\n",
260
+ file_descriptor,
261
+ file_encoding,
262
+ )
263
+ output_cabrillo_line(
264
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
265
+ "\r\n",
266
+ file_descriptor,
267
+ file_encoding,
268
+ )
269
+ output_cabrillo_line(
270
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
271
+ "\r\n",
272
+ file_descriptor,
273
+ file_encoding,
274
+ )
275
+
276
+ output_cabrillo_line(
277
+ f"CLAIMED-SCORE: {calc_score(self)}",
278
+ "\r\n",
279
+ file_descriptor,
280
+ file_encoding,
281
+ )
282
+ ops = f"@{self.station.get('Call','')}"
283
+ list_of_ops = self.database.get_ops()
284
+ for op in list_of_ops:
285
+ ops += f", {op.get('Operator', '')}"
286
+ output_cabrillo_line(
287
+ f"OPERATORS: {ops}",
288
+ "\r\n",
289
+ file_descriptor,
290
+ file_encoding,
291
+ )
292
+ output_cabrillo_line(
293
+ f"NAME: {self.station.get('Name', '')}",
294
+ "\r\n",
295
+ file_descriptor,
296
+ file_encoding,
297
+ )
298
+ output_cabrillo_line(
299
+ f"ADDRESS: {self.station.get('Street1', '')}",
300
+ "\r\n",
301
+ file_descriptor,
302
+ file_encoding,
303
+ )
304
+ output_cabrillo_line(
305
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
306
+ "\r\n",
307
+ file_descriptor,
308
+ file_encoding,
309
+ )
310
+ output_cabrillo_line(
311
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
312
+ "\r\n",
313
+ file_descriptor,
314
+ file_encoding,
315
+ )
316
+ output_cabrillo_line(
317
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
318
+ "\r\n",
319
+ file_descriptor,
320
+ file_encoding,
321
+ )
322
+ output_cabrillo_line(
323
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
324
+ "\r\n",
325
+ file_descriptor,
326
+ file_encoding,
327
+ )
328
+ output_cabrillo_line(
329
+ f"EMAIL: {self.station.get('Email', '')}",
330
+ "\r\n",
331
+ file_descriptor,
332
+ file_encoding,
333
+ )
334
+ for contact in log:
335
+ the_date_and_time = contact.get("TS", "")
336
+ themode = contact.get("Mode", "")
337
+ if themode == "LSB" or themode == "USB":
338
+ themode = "PH"
339
+ if themode == "RTTY":
340
+ themode = "RY"
341
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
342
+
343
+ loggeddate = the_date_and_time[:10]
344
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
345
+ output_cabrillo_line(
346
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
347
+ f"{contact.get('StationPrefix', '').ljust(13)} "
348
+ f"{str(contact.get('SNT', '')).ljust(3)} "
349
+ f"{str(contact.get('SentNr', '')).upper().ljust(6)} "
350
+ f"{contact.get('Call', '').ljust(13)} "
351
+ f"{str(contact.get('RCV', '')).ljust(3)} "
352
+ f"{str(contact.get('Exchange1', '')).upper().ljust(6)}",
353
+ "\r\n",
354
+ file_descriptor,
355
+ file_encoding,
356
+ )
357
+ output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
358
+ self.show_message_box(f"Cabrillo saved to: {filename}")
359
+ except IOError as exception:
360
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
361
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
362
+ return
363
+
364
+
365
+ def trigger_update(self):
366
+ """Triggers the log window to update."""
367
+ cmd = {}
368
+ cmd["cmd"] = "UPDATELOG"
369
+ if self.log_window:
370
+ self.log_window.msg_from_main(cmd)
371
+
372
+
373
+ def recalculate_mults(self):
374
+ """Recalculates multipliers after change in logged qso."""
375
+
376
+
377
+ def process_esm(self, new_focused_widget=None, with_enter=False):
378
+ """ESM State Machine"""
379
+
380
+ # self.pref["run_state"]
381
+
382
+ # -----===== Assigned F-Keys =====-----
383
+ # self.esm_dict["CQ"]
384
+ # self.esm_dict["EXCH"]
385
+ # self.esm_dict["QRZ"]
386
+ # self.esm_dict["AGN"]
387
+ # self.esm_dict["HISCALL"]
388
+ # self.esm_dict["MYCALL"]
389
+ # self.esm_dict["QSOB4"]
390
+
391
+ # ----==== text fields ====----
392
+ # self.callsign
393
+ # self.sent
394
+ # self.receive
395
+ # self.other_1
396
+ # self.other_2
397
+
398
+ if new_focused_widget is not None:
399
+ self.current_widget = self.inputs_dict.get(new_focused_widget)
400
+
401
+ # print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
402
+
403
+ for a_button in [
404
+ self.esm_dict["CQ"],
405
+ self.esm_dict["EXCH"],
406
+ self.esm_dict["QRZ"],
407
+ self.esm_dict["AGN"],
408
+ self.esm_dict["HISCALL"],
409
+ self.esm_dict["MYCALL"],
410
+ self.esm_dict["QSOB4"],
411
+ ]:
412
+ if a_button is not None:
413
+ self.restore_button_color(a_button)
414
+
415
+ buttons_to_send = []
416
+
417
+ if self.pref.get("run_state"):
418
+ if self.current_widget == "callsign":
419
+ if len(self.callsign.text()) < 3:
420
+ self.make_button_green(self.esm_dict["CQ"])
421
+ buttons_to_send.append(self.esm_dict["CQ"])
422
+ elif len(self.callsign.text()) > 2:
423
+ self.make_button_green(self.esm_dict["HISCALL"])
424
+ self.make_button_green(self.esm_dict["EXCH"])
425
+ buttons_to_send.append(self.esm_dict["HISCALL"])
426
+ buttons_to_send.append(self.esm_dict["EXCH"])
427
+
428
+ elif self.current_widget in ["other_2"]:
429
+ if self.other_2.text() == "":
430
+ self.make_button_green(self.esm_dict["AGN"])
431
+ buttons_to_send.append(self.esm_dict["AGN"])
432
+ else:
433
+ self.make_button_green(self.esm_dict["QRZ"])
434
+ buttons_to_send.append(self.esm_dict["QRZ"])
435
+ buttons_to_send.append("LOGIT")
436
+
437
+ if with_enter is True and bool(len(buttons_to_send)):
438
+ for button in buttons_to_send:
439
+ if button:
440
+ if button == "LOGIT":
441
+ self.save_contact()
442
+ continue
443
+ self.process_function_key(button)
444
+ else:
445
+ if self.current_widget == "callsign":
446
+ if len(self.callsign.text()) > 2:
447
+ self.make_button_green(self.esm_dict["MYCALL"])
448
+ buttons_to_send.append(self.esm_dict["MYCALL"])
449
+
450
+ elif self.current_widget in ["other_2"]:
451
+ if self.other_2.text() == "":
452
+ self.make_button_green(self.esm_dict["AGN"])
453
+ buttons_to_send.append(self.esm_dict["AGN"])
454
+ else:
455
+ self.make_button_green(self.esm_dict["EXCH"])
456
+ buttons_to_send.append(self.esm_dict["EXCH"])
457
+ buttons_to_send.append("LOGIT")
458
+
459
+ if with_enter is True and bool(len(buttons_to_send)):
460
+ for button in buttons_to_send:
461
+ if button:
462
+ if button == "LOGIT":
463
+ self.save_contact()
464
+ continue
465
+ self.process_function_key(button)
466
+
467
+
468
+ def populate_history_info_line(self):
469
+ result = self.database.fetch_call_history(self.callsign.text())
470
+ if result:
471
+ self.history_info.setText(f"{result.get('Call', '')}, {result.get('Sect', '')}")
472
+ else:
473
+ self.history_info.setText("")
474
+
475
+
476
+ def check_call_history(self):
477
+ """"""
478
+ result = self.database.fetch_call_history(self.callsign.text())
479
+ if result:
480
+ self.history_info.setText(f"{result.get('UserText','')}")
481
+ if self.other_2.text() == "":
482
+ self.other_2.setText(f"{result.get('Sect', '')}")