not1mm 24.5.1__py3-none-any.whl → 24.5.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. not1mm/__main__.py +18 -10
  2. not1mm/bandmap.py +3 -1
  3. not1mm/checkwindow.py +5 -1
  4. not1mm/data/new_contest.ui +5 -0
  5. not1mm/lib/playsound.py +296 -0
  6. not1mm/lib/version.py +1 -1
  7. not1mm/logwindow.py +5 -1
  8. not1mm/playsoundtest.py +15 -0
  9. not1mm/plugins/10_10_fall_cw.py +2 -0
  10. not1mm/plugins/10_10_spring_cw.py +2 -0
  11. not1mm/plugins/10_10_summer_phone.py +2 -0
  12. not1mm/plugins/10_10_winter_phone.py +2 -0
  13. not1mm/plugins/arrl_10m.py +2 -0
  14. not1mm/plugins/arrl_dx_cw.py +2 -0
  15. not1mm/plugins/arrl_dx_ssb.py +2 -0
  16. not1mm/plugins/arrl_ss_cw.py +2 -0
  17. not1mm/plugins/arrl_ss_phone.py +2 -0
  18. not1mm/plugins/arrl_vhf_jan.py +2 -0
  19. not1mm/plugins/arrl_vhf_jun.py +2 -0
  20. not1mm/plugins/arrl_vhf_sep.py +2 -0
  21. not1mm/plugins/canada_day.py +2 -0
  22. not1mm/plugins/cq_160_cw.py +2 -0
  23. not1mm/plugins/cq_160_ssb.py +2 -0
  24. not1mm/plugins/cq_wpx_cw.py +39 -0
  25. not1mm/plugins/cq_wpx_ssb.py +2 -0
  26. not1mm/plugins/cq_ww_cw.py +2 -0
  27. not1mm/plugins/cq_ww_ssb.py +2 -0
  28. not1mm/plugins/cwt.py +26 -0
  29. not1mm/plugins/general_logging.py +2 -0
  30. not1mm/plugins/iaru_hf.py +2 -0
  31. not1mm/plugins/icwc_mst.py +372 -0
  32. not1mm/plugins/jidx_cw.py +31 -0
  33. not1mm/plugins/jidx_ph.py +2 -0
  34. not1mm/plugins/naqp_cw.py +32 -0
  35. not1mm/plugins/naqp_ssb.py +2 -0
  36. not1mm/plugins/stew_perry_topband.py +2 -0
  37. not1mm/radio.py +12 -9
  38. not1mm/vfo.py +5 -1
  39. not1mm/voice_keying.py +3 -0
  40. {not1mm-24.5.1.dist-info → not1mm-24.5.9.dist-info}/METADATA +8 -3
  41. {not1mm-24.5.1.dist-info → not1mm-24.5.9.dist-info}/RECORD +45 -42
  42. {not1mm-24.5.1.dist-info → not1mm-24.5.9.dist-info}/LICENSE +0 -0
  43. {not1mm-24.5.1.dist-info → not1mm-24.5.9.dist-info}/WHEEL +0 -0
  44. {not1mm-24.5.1.dist-info → not1mm-24.5.9.dist-info}/entry_points.txt +0 -0
  45. {not1mm-24.5.1.dist-info → not1mm-24.5.9.dist-info}/top_level.txt +0 -0
not1mm/__main__.py CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- NOT1MM Logger
3
+ not1mm Contest logger
4
+ Email: michael.bridak@gmail.com
5
+ GPL V3
6
+ Purpose: Provides main logging window and a crap ton more.
4
7
  """
5
8
  # pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines, no-name-in-module
6
9
  # pylint: disable=logging-fstring-interpolation, logging-not-lazy, line-too-long, bare-except
@@ -1247,6 +1250,7 @@ class MainWindow(QtWidgets.QMainWindow):
1247
1250
  else:
1248
1251
  self.cw_speed.hide()
1249
1252
 
1253
+ self.clearinputs()
1250
1254
  cmd = {}
1251
1255
  cmd["cmd"] = "NEWDB"
1252
1256
  cmd["station"] = platform.node()
@@ -1848,6 +1852,7 @@ class MainWindow(QtWidgets.QMainWindow):
1848
1852
  self.contact = self.database.empty_contact
1849
1853
  self.heading_distance.setText("")
1850
1854
  self.dx_entity.setText("")
1855
+
1851
1856
  if self.contest:
1852
1857
  mults = self.contest.show_mults(self)
1853
1858
  qsos = self.contest.show_qso(self)
@@ -1856,13 +1861,16 @@ class MainWindow(QtWidgets.QMainWindow):
1856
1861
  score = self.contest.calc_score(self)
1857
1862
  self.score.setText(str(score))
1858
1863
  self.contest.reset_label(self)
1864
+ if self.contest.name != "ICWC Medium Speed Test":
1865
+ if self.current_mode == "CW":
1866
+ self.sent.setText("599")
1867
+ self.receive.setText("599")
1868
+ else:
1869
+ self.sent.setText("59")
1870
+ self.receive.setText("59")
1871
+ else:
1872
+ self.sent.setText("")
1859
1873
  self.callsign.clear()
1860
- if self.current_mode == "CW":
1861
- self.sent.setText("599")
1862
- self.receive.setText("599")
1863
- else:
1864
- self.sent.setText("59")
1865
- self.receive.setText("59")
1866
1874
  self.other_1.clear()
1867
1875
  self.other_2.clear()
1868
1876
  self.callsign.setFocus()
@@ -3010,15 +3018,16 @@ class MainWindow(QtWidgets.QMainWindow):
3010
3018
  if mode == "CW":
3011
3019
  if self.current_mode != "CW":
3012
3020
  self.current_mode = "CW"
3013
- # self.mode.setText("CW")
3014
3021
  self.sent.setText("599")
3015
3022
  self.receive.setText("599")
3016
3023
  self.read_cw_macros()
3024
+ if self.contest:
3025
+ if self.contest.name == "ICWC Medium Speed Test":
3026
+ self.contest.prefill(self)
3017
3027
  return
3018
3028
  if mode == "SSB":
3019
3029
  if self.current_mode != "SSB":
3020
3030
  self.current_mode = "SSB"
3021
- # self.mode.setText("SSB")
3022
3031
  self.sent.setText("59")
3023
3032
  self.receive.setText("59")
3024
3033
  self.read_cw_macros()
@@ -3026,7 +3035,6 @@ class MainWindow(QtWidgets.QMainWindow):
3026
3035
  if mode == "RTTY":
3027
3036
  if self.current_mode != "RTTY":
3028
3037
  self.current_mode = "RTTY"
3029
- # self.mode.setText("RTTY")
3030
3038
  self.sent.setText("59")
3031
3039
  self.receive.setText("59")
3032
3040
 
not1mm/bandmap.py CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- K6GTE Contest logger
3
+ not1mm Contest logger
4
4
  Email: michael.bridak@gmail.com
5
5
  GPL V3
6
+ Class: BandMapWindow
7
+ Purpose: Onscreen widget to show realtime spots from an AR cluster.
6
8
  """
7
9
 
8
10
  # pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines
not1mm/checkwindow.py CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Check Window
3
+ not1mm Contest logger
4
+ Email: michael.bridak@gmail.com
5
+ GPL V3
6
+ Class: CheckWindow
7
+ Purpose: Onscreen widget to show possible matches to callsigns entered in the main window.
4
8
  """
5
9
  # pylint: disable=no-name-in-module, unused-import, no-member, invalid-name, c-extension-no-member
6
10
  # pylint: disable=logging-fstring-interpolation, line-too-long
@@ -297,6 +297,11 @@
297
297
  <string>CWT</string>
298
298
  </property>
299
299
  </item>
300
+ <item>
301
+ <property name="text">
302
+ <string>ICWC MST</string>
303
+ </property>
304
+ </item>
300
305
  <item>
301
306
  <property name="text">
302
307
  <string>IARU HF</string>
@@ -0,0 +1,296 @@
1
+ import logging
2
+ from platform import system
3
+
4
+ logger = logging.getLogger(__name__)
5
+
6
+
7
+ class PlaysoundException(Exception):
8
+ pass
9
+
10
+
11
+ def _canonicalizePath(path):
12
+ """
13
+ Support passing in a pathlib.Path-like object by converting to str.
14
+ """
15
+ import sys
16
+
17
+ if sys.version_info[0] >= 3:
18
+ return str(path)
19
+ else:
20
+ # On earlier Python versions, str is a byte string, so attempting to
21
+ # convert a unicode string to str will fail. Leave it alone in this case.
22
+ return path
23
+
24
+
25
+ def _playsoundWin(sound, block=True):
26
+ """
27
+ Utilizes windll.winmm. Tested and known to work with MP3 and WAVE on
28
+ Windows 7 with Python 2.7. Probably works with more file formats.
29
+ Probably works on Windows XP thru Windows 10. Probably works with all
30
+ versions of Python.
31
+
32
+ Inspired by (but not copied from) Michael Gundlach <gundlach@gmail.com>'s mp3play:
33
+ https://github.com/michaelgundlach/mp3play
34
+
35
+ I never would have tried using windll.winmm without seeing his code.
36
+ """
37
+ sound = '"' + _canonicalizePath(sound) + '"'
38
+
39
+ from ctypes import create_unicode_buffer, windll, wintypes
40
+
41
+ windll.winmm.mciSendStringW.argtypes = [
42
+ wintypes.LPCWSTR,
43
+ wintypes.LPWSTR,
44
+ wintypes.UINT,
45
+ wintypes.HANDLE,
46
+ ]
47
+ windll.winmm.mciGetErrorStringW.argtypes = [
48
+ wintypes.DWORD,
49
+ wintypes.LPWSTR,
50
+ wintypes.UINT,
51
+ ]
52
+
53
+ def winCommand(*command):
54
+ bufLen = 600
55
+ buf = create_unicode_buffer(bufLen)
56
+ command = " ".join(command)
57
+ errorCode = int(
58
+ windll.winmm.mciSendStringW(command, buf, bufLen - 1, 0)
59
+ ) # use widestring version of the function
60
+ if errorCode:
61
+ errorBuffer = create_unicode_buffer(bufLen)
62
+ windll.winmm.mciGetErrorStringW(
63
+ errorCode, errorBuffer, bufLen - 1
64
+ ) # use widestring version of the function
65
+ exceptionMessage = (
66
+ "\n Error " + str(errorCode) + " for command:"
67
+ "\n " + command + "\n " + errorBuffer.value
68
+ )
69
+ logger.error(exceptionMessage)
70
+ raise PlaysoundException(exceptionMessage)
71
+ return buf.value
72
+
73
+ try:
74
+ logger.debug("Starting")
75
+ winCommand("open {}".format(sound))
76
+ winCommand("play {}{}".format(sound, " wait" if block else ""))
77
+ logger.debug("Returning")
78
+ finally:
79
+ try:
80
+ winCommand("close {}".format(sound))
81
+ except PlaysoundException:
82
+ logger.warning("Failed to close the file: {}".format(sound))
83
+ # If it fails, there's nothing more that can be done...
84
+ pass
85
+
86
+
87
+ def _handlePathOSX(sound):
88
+ sound = _canonicalizePath(sound)
89
+
90
+ if "://" not in sound:
91
+ if not sound.startswith("/"):
92
+ from os import getcwd
93
+
94
+ sound = getcwd() + "/" + sound
95
+ sound = "file://" + sound
96
+
97
+ try:
98
+ # Don't double-encode it.
99
+ sound.encode("ascii")
100
+ return sound.replace(" ", "%20")
101
+ except UnicodeEncodeError:
102
+ try:
103
+ from urllib.parse import quote # Try the Python 3 import first...
104
+ except ImportError:
105
+ from urllib import (
106
+ quote,
107
+ ) # Try using the Python 2 import before giving up entirely...
108
+
109
+ parts = sound.split("://", 1)
110
+ return parts[0] + "://" + quote(parts[1].encode("utf-8")).replace(" ", "%20")
111
+
112
+
113
+ def _playsoundOSX(sound, block=True):
114
+ """
115
+ Utilizes AppKit.NSSound. Tested and known to work with MP3 and WAVE on
116
+ OS X 10.11 with Python 2.7. Probably works with anything QuickTime supports.
117
+ Probably works on OS X 10.5 and newer. Probably works with all versions of
118
+ Python.
119
+
120
+ Inspired by (but not copied from) Aaron's Stack Overflow answer here:
121
+ http://stackoverflow.com/a/34568298/901641
122
+
123
+ I never would have tried using AppKit.NSSound without seeing his code.
124
+ """
125
+ try:
126
+ from AppKit import NSSound
127
+ except ImportError:
128
+ logger.warning(
129
+ "playsound could not find a copy of AppKit - falling back to using macOS's system copy."
130
+ )
131
+ sys.path.append(
132
+ "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC"
133
+ )
134
+ from AppKit import NSSound
135
+
136
+ from Foundation import NSURL
137
+ from time import sleep
138
+
139
+ sound = _handlePathOSX(sound)
140
+ url = NSURL.URLWithString_(sound)
141
+ if not url:
142
+ raise PlaysoundException("Cannot find a sound with filename: " + sound)
143
+
144
+ for i in range(5):
145
+ nssound = NSSound.alloc().initWithContentsOfURL_byReference_(url, True)
146
+ if nssound:
147
+ break
148
+ else:
149
+ logger.debug("Failed to load sound, although url was good... " + sound)
150
+ else:
151
+ raise PlaysoundException(
152
+ "Could not load sound with filename, although URL was good... " + sound
153
+ )
154
+ nssound.play()
155
+
156
+ if block:
157
+ sleep(nssound.duration())
158
+
159
+
160
+ def _playsoundNix(sound, block=True):
161
+ """Play a sound using GStreamer.
162
+
163
+ Inspired by this:
164
+ https://gstreamer.freedesktop.org/documentation/tutorials/playback/playbin-usage.html
165
+ """
166
+ sound = _canonicalizePath(sound)
167
+
168
+ # pathname2url escapes non-URL-safe characters
169
+ from os.path import abspath, exists
170
+
171
+ try:
172
+ from urllib.request import pathname2url
173
+ except ImportError:
174
+ # python 2
175
+ from urllib import pathname2url
176
+
177
+ import gi
178
+
179
+ gi.require_version("Gst", "1.0")
180
+ from gi.repository import Gst
181
+
182
+ Gst.init(None)
183
+
184
+ playbin = Gst.ElementFactory.make("playbin", "playbin")
185
+ if sound.startswith(("http://", "https://")):
186
+ playbin.props.uri = sound
187
+ else:
188
+ path = abspath(sound)
189
+ if not exists(path):
190
+ raise PlaysoundException("File not found: {}".format(path))
191
+ playbin.props.uri = "file://" + pathname2url(path)
192
+
193
+ set_result = playbin.set_state(Gst.State.PLAYING)
194
+ if set_result != Gst.StateChangeReturn.ASYNC:
195
+ raise PlaysoundException("playbin.set_state returned " + repr(set_result))
196
+
197
+ # FIXME: use some other bus method than poll() with block=False
198
+ # https://lazka.github.io/pgi-docs/#Gst-1.0/classes/Bus.html
199
+ logger.debug("Starting play")
200
+ if block:
201
+ bus = playbin.get_bus()
202
+ try:
203
+ bus.poll(Gst.MessageType.EOS, Gst.CLOCK_TIME_NONE)
204
+ finally:
205
+ playbin.set_state(Gst.State.NULL)
206
+
207
+ logger.debug("Finishing play")
208
+
209
+
210
+ def _playsoundAnotherPython(otherPython, sound, block=True, macOS=False):
211
+ """
212
+ Mostly written so that when this is run on python3 on macOS, it can invoke
213
+ python2 on macOS... but maybe this idea could be useful on linux, too.
214
+ """
215
+ from inspect import getsourcefile
216
+ from os.path import abspath, exists
217
+ from subprocess import check_call
218
+ from threading import Thread
219
+
220
+ sound = _canonicalizePath(sound)
221
+
222
+ class PropogatingThread(Thread):
223
+ def run(self):
224
+ self.exc = None
225
+ try:
226
+ self.ret = self._target(*self._args, **self._kwargs)
227
+ except BaseException as e:
228
+ self.exc = e
229
+
230
+ def join(self, timeout=None):
231
+ super().join(timeout)
232
+ if self.exc:
233
+ raise self.exc
234
+ return self.ret
235
+
236
+ # Check if the file exists...
237
+ if not exists(abspath(sound)):
238
+ raise PlaysoundException("Cannot find a sound with filename: " + sound)
239
+
240
+ playsoundPath = abspath(getsourcefile(lambda: 0))
241
+ t = PropogatingThread(
242
+ target=lambda: check_call(
243
+ [otherPython, playsoundPath, _handlePathOSX(sound) if macOS else sound]
244
+ )
245
+ )
246
+ t.start()
247
+ if block:
248
+ t.join()
249
+
250
+
251
+ system = system()
252
+
253
+ if system == "Windows":
254
+ playsound = _playsoundWin
255
+ elif system == "Darwin":
256
+ playsound = _playsoundOSX
257
+ import sys
258
+
259
+ if sys.version_info[0] > 2:
260
+ try:
261
+ from AppKit import NSSound
262
+ except ImportError:
263
+ logger.warning(
264
+ "playsound is relying on a python 2 subprocess. Please use `pip3 install PyObjC` if you want playsound to run more efficiently."
265
+ )
266
+ playsound = lambda sound, block=True: _playsoundAnotherPython(
267
+ "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python",
268
+ sound,
269
+ block,
270
+ macOS=True,
271
+ )
272
+ else:
273
+ playsound = _playsoundNix
274
+ if (
275
+ __name__ != "__main__"
276
+ ): # Ensure we don't infinitely recurse trying to get another python instance.
277
+ try:
278
+ import gi
279
+
280
+ gi.require_version("Gst", "1.0")
281
+ from gi.repository import Gst
282
+ except:
283
+ logger.warning(
284
+ "playsound is relying on another python subprocess. Please use `pip install pygobject` if you want playsound to run more efficiently."
285
+ )
286
+ playsound = lambda sound, block=True: _playsoundAnotherPython(
287
+ "/usr/bin/python3", sound, block, macOS=False
288
+ )
289
+
290
+ del system
291
+
292
+ if __name__ == "__main__":
293
+ # block is always True if you choose to run this from the command line.
294
+ from sys import argv
295
+
296
+ playsound(argv[1])
not1mm/lib/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.5.1"
3
+ __version__ = "24.5.9"
not1mm/logwindow.py CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Display current log
3
+ not1mm Contest logger
4
+ Email: michael.bridak@gmail.com
5
+ GPL V3
6
+ Class: LogWindow
7
+ Purpose: Onscreen widget to show and edit logged contacts.
4
8
  """
5
9
  # pylint: disable=no-name-in-module, unused-import, no-member, c-extension-no-member
6
10
  # pylint: disable=logging-fstring-interpolation, too-many-lines
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ NOT1MM Logger
4
+ Purpose: test alternative sound playing interface
5
+ """
6
+ # pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines, no-name-in-module
7
+ # pylint: disable=logging-fstring-interpolation, logging-not-lazy, line-too-long, bare-except
8
+
9
+ from not1mm.lib.playsound import playsound
10
+
11
+ import not1mm.fsutils as fsutils
12
+
13
+ filename = fsutils.APP_DATA_PATH / "phonetics/cq.wav"
14
+
15
+ playsound(filename, True)
@@ -48,6 +48,8 @@ def interface(self):
48
48
  self.field2.show()
49
49
  self.field3.hide()
50
50
  self.field4.show()
51
+ self.snt_label.setText("SNT")
52
+ self.field1.setAccessibleName("RST Sent")
51
53
  label = self.field4.findChild(QtWidgets.QLabel)
52
54
  label.setText("Name 1010# SPC")
53
55
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -47,6 +47,8 @@ def interface(self):
47
47
  self.field2.show()
48
48
  self.field3.hide()
49
49
  self.field4.show()
50
+ self.snt_label.setText("SNT")
51
+ self.field1.setAccessibleName("RST Sent")
50
52
  label = self.field4.findChild(QtWidgets.QLabel)
51
53
  label.setText("Name 1010# SPC")
52
54
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -49,6 +49,8 @@ def interface(self):
49
49
  self.field2.show()
50
50
  self.field3.hide()
51
51
  self.field4.show()
52
+ self.snt_label.setText("SNT")
53
+ self.field1.setAccessibleName("RST Sent")
52
54
  label = self.field4.findChild(QtWidgets.QLabel)
53
55
  label.setText("Name 1010# SPC")
54
56
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -49,6 +49,8 @@ def interface(self):
49
49
  self.field2.show()
50
50
  self.field3.hide()
51
51
  self.field4.show()
52
+ self.snt_label.setText("SNT")
53
+ self.field1.setAccessibleName("RST Sent")
52
54
  label = self.field4.findChild(QtWidgets.QLabel)
53
55
  label.setText("Name 1010# SPC")
54
56
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -94,6 +94,8 @@ def interface(self):
94
94
  self.field2.show()
95
95
  self.field3.show()
96
96
  self.field4.show()
97
+ self.snt_label.setText("SNT")
98
+ self.field1.setAccessibleName("RST Sent")
97
99
  label = self.field3.findChild(QtWidgets.QLabel)
98
100
  label.setText("SentNR")
99
101
  self.field3.setAccessibleName("Sent Number")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  label = self.field4.findChild(QtWidgets.QLabel)
57
59
  label.setText("Power")
58
60
  self.field4.setAccessibleName("Power")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  label = self.field4.findChild(QtWidgets.QLabel)
57
59
  label.setText("Power")
58
60
  self.field4.setAccessibleName("Power")
@@ -52,6 +52,8 @@ def interface(self):
52
52
  self.field2.show()
53
53
  self.field3.show()
54
54
  self.field4.show()
55
+ self.snt_label.setText("SNT")
56
+ self.field1.setAccessibleName("RST Sent")
55
57
  label = self.field3.findChild(QtWidgets.QLabel)
56
58
  label.setText("SentNR")
57
59
  self.field3.setAccessibleName("Sent Number")
@@ -52,6 +52,8 @@ def interface(self):
52
52
  self.field2.show()
53
53
  self.field3.show()
54
54
  self.field4.show()
55
+ self.snt_label.setText("SNT")
56
+ self.field1.setAccessibleName("RST Sent")
55
57
  label = self.field3.findChild(QtWidgets.QLabel)
56
58
  label.setText("SentNR")
57
59
  self.field3.setAccessibleName("Sent Number")
@@ -83,6 +83,8 @@ def interface(self):
83
83
  self.field2.show()
84
84
  self.field3.show()
85
85
  self.field4.show()
86
+ self.snt_label.setText("SNT")
87
+ self.field1.setAccessibleName("RST Sent")
86
88
  label = self.field3.findChild(QtWidgets.QLabel)
87
89
  label.setText("SentNR")
88
90
  self.field3.setAccessibleName("Sent Grid")
@@ -51,6 +51,8 @@ def interface(self):
51
51
  self.field2.show()
52
52
  self.field3.show()
53
53
  self.field4.show()
54
+ self.snt_label.setText("SNT")
55
+ self.field1.setAccessibleName("RST Sent")
54
56
  label = self.field3.findChild(QtWidgets.QLabel)
55
57
  label.setText("SentNR")
56
58
  self.field3.setAccessibleName("Sent Grid")
@@ -51,6 +51,8 @@ def interface(self):
51
51
  self.field2.show()
52
52
  self.field3.show()
53
53
  self.field4.show()
54
+ self.snt_label.setText("SNT")
55
+ self.field1.setAccessibleName("RST Sent")
54
56
  label = self.field3.findChild(QtWidgets.QLabel)
55
57
  label.setText("SentNR")
56
58
  self.field3.setAccessibleName("Sent Grid")
@@ -84,6 +84,8 @@ def interface(self):
84
84
  self.field2.show()
85
85
  self.field3.show()
86
86
  self.field4.show()
87
+ self.snt_label.setText("SNT")
88
+ self.field1.setAccessibleName("RST Sent")
87
89
  label = self.field3.findChild(QtWidgets.QLabel)
88
90
  label.setText("SentNR")
89
91
  self.field3.setAccessibleName("Sent Number")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  # self.other_label.setText("SentNR")
57
59
  # self.field3.setAccessibleName("Sent Number")
58
60
  self.exch_label.setText("ST/Prov/CQ Zone")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  # self.other_label.setText("SentNR")
57
59
  # self.field3.setAccessibleName("Sent Number")
58
60
  self.exch_label.setText("ST/Prov/CQ Zone")
@@ -2,6 +2,43 @@
2
2
 
3
3
  # pylint: disable=invalid-name, c-extension-no-member, unused-import
4
4
 
5
+ # CQ WW WPX Contest, CW
6
+ # Status: Active
7
+ # Geographic Focus: Worldwide
8
+ # Participation: Worldwide
9
+ # Awards: Worldwide
10
+ # Mode: CW
11
+ # Bands: 160, 80, 40, 20, 15, 10m
12
+ # Classes: Single Op All Band (QRP/Low/High)
13
+ # Single Op Single Band (QRP/Low/High)
14
+ # Single Op Overlays: (TB-Wires/Rookie/Classic/Youth)
15
+ # Multi-Single (Low/High)
16
+ # Multi-Two
17
+ # Multi-Multi
18
+ # Multi-Distributed
19
+ # Max operating hours: Single Op: 36 hours with offtimes of at least 60 minutes
20
+ # Multi-Op: 48 hours
21
+ # Max power: HP: 1500 watts
22
+ # LP: 100 watts
23
+ # QRP: 5 watts
24
+ # Exchange: RST + Serial No.
25
+ # Work stations: Once per band
26
+ # QSO Points: All: 6 points per 160/80/40m QSO with different continent
27
+ # All: 3 points per 20/15/10m QSO with different continent
28
+ # Non-NA: 2 points per 160/80/40m QSO with same continent different country
29
+ # Non-NA: 1 point per 20/15/10m QSO with same continent different country
30
+ # NA: 4 points per 160/80/40m QSO with same continent different country
31
+ # NA: 2 points per 20/15/10m QSO with same continent different country
32
+ # All: 1 point per QSO with same country
33
+ # Multipliers: Prefixes once
34
+ # Score Calculation: Total score = total QSO points x total mults
35
+ # E-mail logs to: (none)
36
+ # Upload log at: https://www.cqwpx.com/logcheck/
37
+ # Mail logs to: (none)
38
+ # Find rules at: https://www.cqwpx.com/rules.htm
39
+ # Cabrillo name: CQ-WPX-CW
40
+
41
+
5
42
  import datetime
6
43
  import logging
7
44
 
@@ -53,6 +90,8 @@ def interface(self):
53
90
  self.field2.show()
54
91
  self.field3.show()
55
92
  self.field4.show()
93
+ self.snt_label.setText("SNT")
94
+ self.field1.setAccessibleName("RST Sent")
56
95
  self.other_label.setText("SentNR")
57
96
  self.field3.setAccessibleName("Sent Number")
58
97
  self.exch_label.setText("RcvNR")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.show()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  label = self.field3.findChild(QtWidgets.QLabel)
57
59
  label.setText("SentNR")
58
60
  self.field3.setAccessibleName("Sent Number")
@@ -51,6 +51,8 @@ def interface(self):
51
51
  self.field2.show()
52
52
  self.field3.hide()
53
53
  self.field4.show()
54
+ self.snt_label.setText("SNT")
55
+ self.field1.setAccessibleName("RST Sent")
54
56
  label = self.field4.findChild(QtWidgets.QLabel)
55
57
  label.setText("CQ Zone")
56
58
  self.field4.setAccessibleName("C Q Zone")