not1mm 24.3.9__py3-none-any.whl → 24.3.19__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 (43) hide show
  1. not1mm/__main__.py +2 -4
  2. not1mm/data/new_contest.ui +11 -1
  3. not1mm/data/not1mm.html +46 -108
  4. not1mm/lib/database.py +14 -0
  5. not1mm/lib/plugin_common.py +29 -2
  6. not1mm/lib/version.py +1 -1
  7. not1mm/plugins/10_10_fall_cw.py +2 -0
  8. not1mm/plugins/10_10_spring_cw.py +2 -0
  9. not1mm/plugins/10_10_summer_phone.py +2 -0
  10. not1mm/plugins/10_10_winter_phone.py +2 -0
  11. not1mm/plugins/arrl_10m.py +2 -0
  12. not1mm/plugins/arrl_dx_cw.py +2 -0
  13. not1mm/plugins/arrl_dx_ssb.py +2 -0
  14. not1mm/plugins/arrl_field_day.py +2 -0
  15. not1mm/plugins/arrl_ss_cw.py +2 -0
  16. not1mm/plugins/arrl_ss_phone.py +2 -0
  17. not1mm/plugins/arrl_vhf_jan.py +2 -0
  18. not1mm/plugins/arrl_vhf_jun.py +2 -0
  19. not1mm/plugins/arrl_vhf_sep.py +2 -0
  20. not1mm/plugins/canada_day.py +2 -0
  21. not1mm/plugins/cq_160_cw.py +411 -0
  22. not1mm/plugins/cq_160_ssb.py +411 -0
  23. not1mm/plugins/cq_wpx_cw.py +2 -0
  24. not1mm/plugins/cq_wpx_ssb.py +2 -0
  25. not1mm/plugins/cq_ww_cw.py +2 -0
  26. not1mm/plugins/cq_ww_ssb.py +2 -0
  27. not1mm/plugins/cwt.py +2 -0
  28. not1mm/plugins/iaru_hf.py +2 -0
  29. not1mm/plugins/jidx_cw.py +2 -0
  30. not1mm/plugins/jidx_ph.py +2 -0
  31. not1mm/plugins/naqp_cw.py +2 -0
  32. not1mm/plugins/naqp_ssb.py +2 -0
  33. not1mm/plugins/phone_weekly_test.py +2 -0
  34. not1mm/plugins/stew_perry_topband.py +2 -0
  35. not1mm/plugins/winter_field_day.py +2 -0
  36. {not1mm-24.3.9.dist-info → not1mm-24.3.19.dist-info}/METADATA +7 -1
  37. {not1mm-24.3.9.dist-info → not1mm-24.3.19.dist-info}/RECORD +43 -40
  38. {not1mm-24.3.9.dist-info → not1mm-24.3.19.dist-info}/WHEEL +1 -1
  39. testing/detectdark.py +35 -0
  40. testing/test.py +13 -11
  41. {not1mm-24.3.9.dist-info → not1mm-24.3.19.dist-info}/LICENSE +0 -0
  42. {not1mm-24.3.9.dist-info → not1mm-24.3.19.dist-info}/entry_points.txt +0 -0
  43. {not1mm-24.3.9.dist-info → not1mm-24.3.19.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,411 @@
1
+ """CQ 160 CW plugin"""
2
+
3
+ # pylint: disable=invalid-name, c-extension-no-member, unused-import, line-too-long, too-many-lines, no-name-in-module
4
+
5
+ import datetime
6
+ import logging
7
+ import platform
8
+
9
+ from pathlib import Path
10
+
11
+ from PyQt5 import QtWidgets
12
+
13
+ from not1mm.lib.plugin_common import gen_adif
14
+ from not1mm.lib.version import __version__
15
+
16
+ logger = logging.getLogger("__main__")
17
+
18
+ name = "CQ 160 SSB"
19
+ cabrillo_name = "CQ-160-SSB"
20
+ mode = "SSB" # CW SSB BOTH RTTY
21
+
22
+ columns = [
23
+ "YYYY-MM-DD HH:MM:SS",
24
+ "Call",
25
+ "Freq",
26
+ "Snt",
27
+ "Rcv",
28
+ "PFX",
29
+ "Exchange1",
30
+ "M1",
31
+ "PTS",
32
+ ]
33
+
34
+ advance_on_space = [True, True, True, True, True]
35
+
36
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
37
+ dupe_type = 1
38
+
39
+
40
+ def init_contest(self):
41
+ """setup plugin"""
42
+ set_tab_next(self)
43
+ set_tab_prev(self)
44
+ interface(self)
45
+ self.next_field = self.other_2
46
+
47
+
48
+ def interface(self):
49
+ """Setup user interface"""
50
+ self.field1.show()
51
+ self.field2.show()
52
+ self.field3.hide()
53
+ self.field4.show()
54
+ # self.other_label.setText("SentNR")
55
+ # self.field3.setAccessibleName("Sent Number")
56
+ self.exch_label.setText("ST/Prov/CQ Zone")
57
+ self.field4.setAccessibleName("Received Exchange")
58
+
59
+
60
+ def reset_label(self): # pylint: disable=unused-argument
61
+ """reset label after field cleared"""
62
+
63
+
64
+ def set_tab_next(self):
65
+ """Set TAB Advances"""
66
+ self.tab_next = {
67
+ self.callsign: self.field1.findChild(QtWidgets.QLineEdit),
68
+ self.field1.findChild(QtWidgets.QLineEdit): self.field2.findChild(
69
+ QtWidgets.QLineEdit
70
+ ),
71
+ self.field2.findChild(QtWidgets.QLineEdit): self.field4.findChild(
72
+ QtWidgets.QLineEdit
73
+ ),
74
+ self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
75
+ QtWidgets.QLineEdit
76
+ ),
77
+ self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
78
+ }
79
+
80
+
81
+ def set_tab_prev(self):
82
+ """Set TAB Advances"""
83
+ self.tab_prev = {
84
+ self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
85
+ self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
86
+ self.field2.findChild(QtWidgets.QLineEdit): self.field1.findChild(
87
+ QtWidgets.QLineEdit
88
+ ),
89
+ self.field3.findChild(QtWidgets.QLineEdit): self.field2.findChild(
90
+ QtWidgets.QLineEdit
91
+ ),
92
+ self.field4.findChild(QtWidgets.QLineEdit): self.field2.findChild(
93
+ QtWidgets.QLineEdit
94
+ ),
95
+ }
96
+
97
+
98
+ def set_contact_vars(self):
99
+ """Contest Specific"""
100
+ self.contact["SNT"] = self.sent.text()
101
+ self.contact["RCV"] = self.receive.text()
102
+ self.contact["SentNr"] = self.contest_settings.get("SentExchange", 0)
103
+ self.contact["Exchange1"] = self.other_2.text()
104
+ self.contact["IsMultiplier1"] = 0
105
+ # check if mult
106
+ if "/MM" in self.contact.get("Call", ""):
107
+ return
108
+ if self.contact["CountryPrefix"] == "K":
109
+ # check unique state.
110
+ query = f"select count(*) as count from dxlog where CountryPrefix = 'K' and Exchange1 = '{self.contact.get('Exchange1', '')}' and ContestNR = '{self.pref.get('contest', '0')}'"
111
+ result = self.database.exec_sql(query)
112
+ if result.get("count", 0) > 0:
113
+ self.contact["IsMultiplier1"] = 0
114
+ else:
115
+ self.contact["IsMultiplier1"] = 1
116
+ return
117
+ if self.contact["CountryPrefix"] == "VE":
118
+ # check unique province.
119
+ query = f"select count(*) as count from dxlog where CountryPrefix = 'VE' and Exchange1 = '{self.contact.get('Exchange1', '')}' and ContestNR = '{self.pref.get('contest', '0')}'"
120
+ result = self.database.exec_sql(query)
121
+ if result.get("count", 0) > 0:
122
+ self.contact["IsMultiplier1"] = 0
123
+ else:
124
+ self.contact["IsMultiplier1"] = 1
125
+ return
126
+ # check all others
127
+ query = f"select count(*) as count from dxlog where CountryPrefix = '{self.contact.get('CountryPrefix', '')}' and ContestNR = '{self.pref.get('contest', '0')}'"
128
+ result = self.database.exec_sql(query)
129
+ if result.get("count", 0) > 0:
130
+ self.contact["IsMultiplier1"] = 0
131
+ else:
132
+ self.contact["IsMultiplier1"] = 1
133
+ return
134
+
135
+
136
+ def predupe(self): # pylint: disable=unused-argument
137
+ """called after callsign entered"""
138
+
139
+
140
+ def prefill(self):
141
+ """Fill SentNR"""
142
+
143
+
144
+ def points(self):
145
+ """Calc point"""
146
+ # Maritime Mobile
147
+ if "/MM" in self.contact.get("Call", ""):
148
+ return 5
149
+
150
+ result = self.cty_lookup(self.station.get("Call", ""))
151
+ if result:
152
+ for item in result.items():
153
+ mycountry = item[1].get("entity", "")
154
+ mycontinent = item[1].get("continent", "")
155
+ result = self.cty_lookup(self.contact.get("Call", ""))
156
+ if result:
157
+ for item in result.items():
158
+ entity = item[1].get("entity", "")
159
+ continent = item[1].get("continent", "")
160
+
161
+ # Both in same country
162
+ if mycountry.upper() == entity.upper():
163
+ return 2
164
+
165
+ # Same Continent
166
+ if mycontinent == continent:
167
+ return 5
168
+
169
+ # Different Continent
170
+ return 10
171
+ return 0
172
+
173
+
174
+ def show_mults(self):
175
+ """Return display string for mults"""
176
+ result = self.database.fetch_mult1_count()
177
+ count = result.get("count", 0)
178
+ return count
179
+
180
+
181
+ def show_qso(self):
182
+ """Return qso count"""
183
+ result = self.database.fetch_qso_count()
184
+ if result:
185
+ return int(result.get("qsos", 0))
186
+ return 0
187
+
188
+
189
+ def calc_score(self):
190
+ """Return calculated score"""
191
+ result = self.database.fetch_points()
192
+ if result is not None:
193
+ score = result.get("Points", "0")
194
+ if score is None:
195
+ score = "0"
196
+ contest_points = int(score)
197
+ result = self.database.fetch_mult1_count()
198
+ mults = int(result.get("count", 0))
199
+ return contest_points * mults
200
+ return 0
201
+
202
+
203
+ def adif(self):
204
+ """Call the generate ADIF function"""
205
+ gen_adif(self, cabrillo_name, "CQ-160-SSB")
206
+
207
+
208
+ def cabrillo(self):
209
+ """Generates Cabrillo file. Maybe."""
210
+ # https://www.cw160.com/cabrillo.htm
211
+ logger.debug("******Cabrillo*****")
212
+ logger.debug("Station: %s", f"{self.station}")
213
+ logger.debug("Contest: %s", f"{self.contest_settings}")
214
+ now = datetime.datetime.now()
215
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
216
+ filename = (
217
+ str(Path.home())
218
+ + "/"
219
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
220
+ )
221
+ logger.debug("%s", filename)
222
+ log = self.database.fetch_all_contacts_asc()
223
+ try:
224
+ with open(filename, "w", encoding="ascii") as file_descriptor:
225
+ print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
226
+ print(
227
+ f"CREATED-BY: Not1MM v{__version__}",
228
+ end="\r\n",
229
+ file=file_descriptor,
230
+ )
231
+ print(
232
+ f"CONTEST: {cabrillo_name}",
233
+ end="\r\n",
234
+ file=file_descriptor,
235
+ )
236
+ if self.station.get("Club", ""):
237
+ print(
238
+ f"CLUB: {self.station.get('Club', '').upper()}",
239
+ end="\r\n",
240
+ file=file_descriptor,
241
+ )
242
+ print(
243
+ f"CALLSIGN: {self.station.get('Call','')}",
244
+ end="\r\n",
245
+ file=file_descriptor,
246
+ )
247
+ print(
248
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
249
+ end="\r\n",
250
+ file=file_descriptor,
251
+ )
252
+
253
+ print(
254
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
255
+ end="\r\n",
256
+ file=file_descriptor,
257
+ )
258
+ print(
259
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
260
+ end="\r\n",
261
+ file=file_descriptor,
262
+ )
263
+ print(
264
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
265
+ end="\r\n",
266
+ file=file_descriptor,
267
+ )
268
+ print(
269
+ f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
270
+ end="\r\n",
271
+ file=file_descriptor,
272
+ )
273
+ print(
274
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
275
+ end="\r\n",
276
+ file=file_descriptor,
277
+ )
278
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
279
+ print(
280
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
281
+ end="\r\n",
282
+ file=file_descriptor,
283
+ )
284
+ print(
285
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
286
+ end="\r\n",
287
+ file=file_descriptor,
288
+ )
289
+
290
+ print(
291
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
292
+ end="\r\n",
293
+ file=file_descriptor,
294
+ )
295
+
296
+ print(
297
+ f"CLAIMED-SCORE: {calc_score(self)}",
298
+ end="\r\n",
299
+ file=file_descriptor,
300
+ )
301
+ ops = f"@{self.station.get('Call','')}"
302
+ list_of_ops = self.database.get_ops()
303
+ for op in list_of_ops:
304
+ ops += f", {op.get('Operator', '')}"
305
+ print(
306
+ f"OPERATORS: {ops}",
307
+ end="\r\n",
308
+ file=file_descriptor,
309
+ )
310
+ print(
311
+ f"NAME: {self.station.get('Name', '')}",
312
+ end="\r\n",
313
+ file=file_descriptor,
314
+ )
315
+ print(
316
+ f"ADDRESS: {self.station.get('Street1', '')}",
317
+ end="\r\n",
318
+ file=file_descriptor,
319
+ )
320
+ print(
321
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
322
+ end="\r\n",
323
+ file=file_descriptor,
324
+ )
325
+ print(
326
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
327
+ end="\r\n",
328
+ file=file_descriptor,
329
+ )
330
+ print(
331
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
332
+ end="\r\n",
333
+ file=file_descriptor,
334
+ )
335
+ print(
336
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
337
+ end="\r\n",
338
+ file=file_descriptor,
339
+ )
340
+ print(
341
+ f"EMAIL: {self.station.get('Email', '')}",
342
+ end="\r\n",
343
+ file=file_descriptor,
344
+ )
345
+ for contact in log:
346
+ the_date_and_time = contact.get("TS", "")
347
+ themode = contact.get("Mode", "")
348
+ if themode == "LSB" or themode == "USB":
349
+ themode = "PH"
350
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
351
+
352
+ loggeddate = the_date_and_time[:10]
353
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
354
+ print(
355
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
356
+ f"{contact.get('StationPrefix', '').ljust(13)} "
357
+ f"{str(contact.get('SNT', '')).ljust(3)} "
358
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
359
+ f"{contact.get('Call', '').ljust(13)} "
360
+ f"{str(contact.get('RCV', '')).ljust(3)} "
361
+ f"{str(contact.get('Exchange1', '')).ljust(6)}",
362
+ end="\r\n",
363
+ file=file_descriptor,
364
+ )
365
+ print("END-OF-LOG:", end="\r\n", file=file_descriptor)
366
+ self.show_message_box(f"Cabrillo saved to: {filename}")
367
+ except IOError as exception:
368
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
369
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
370
+ return
371
+
372
+
373
+ def trigger_update(self):
374
+ """Triggers the log window to update."""
375
+ cmd = {}
376
+ cmd["cmd"] = "UPDATELOG"
377
+ cmd["station"] = platform.node()
378
+ self.multicast_interface.send_as_json(cmd)
379
+
380
+
381
+ def recalculate_mults(self):
382
+ """Recalculates multipliers after change in logged qso."""
383
+ all_contacts = self.database.fetch_all_contacts_asc()
384
+ for contact in all_contacts:
385
+ time_stamp = contact.get("TS", "")
386
+ if contact.get("CountryPrefix", "") == "K":
387
+ query = f"select count(*) as count from dxlog where TS < '{time_stamp}' and CountryPrefix = 'K' and Exchange1 = '{contact.get('Exchange1', '')}' and ContestNR = '{self.pref.get('contest', '0')}'"
388
+ result = self.database.exec_sql(query)
389
+ if result.get("count", 0) == 0:
390
+ contact["IsMultiplier1"] = 1
391
+ else:
392
+ contact["IsMultiplier1"] = 0
393
+ self.database.change_contact(contact)
394
+ continue
395
+ if contact.get("CountryPrefix", "") == "VE":
396
+ query = f"select count(*) as count from dxlog where TS < '{time_stamp}' and CountryPrefix = 'VE' and Exchange1 = '{contact.get('Exchange1', '')}' and ContestNR = '{self.pref.get('contest', '0')}'"
397
+ result = self.database.exec_sql(query)
398
+ if result.get("count", 0) == 0:
399
+ contact["IsMultiplier1"] = 1
400
+ else:
401
+ contact["IsMultiplier1"] = 0
402
+ self.database.change_contact(contact)
403
+ continue
404
+ query = f"select count(*) as count from dxlog where TS < '{time_stamp}' and CountryPrefix = '{contact.get('CountryPrefix', '')}' and ContestNR = '{self.pref.get('contest', '0')}'"
405
+ result = self.database.exec_sql(query)
406
+ if result.get("count", 0) == 0:
407
+ contact["IsMultiplier1"] = 1
408
+ else:
409
+ contact["IsMultiplier1"] = 0
410
+ self.database.change_contact(contact)
411
+ trigger_update(self)
@@ -362,8 +362,10 @@ def cabrillo(self):
362
362
  file=file_descriptor,
363
363
  )
364
364
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
365
+ self.show_message_box(f"Cabrillo saved to: {filename}")
365
366
  except IOError as exception:
366
367
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
368
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
367
369
  return
368
370
 
369
371
 
@@ -364,8 +364,10 @@ def cabrillo(self):
364
364
  file=file_descriptor,
365
365
  )
366
366
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
367
+ self.show_message_box(f"Cabrillo saved to: {filename}")
367
368
  except IOError as exception:
368
369
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
370
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
369
371
  return
370
372
 
371
373
 
@@ -333,8 +333,10 @@ def cabrillo(self):
333
333
  file=file_descriptor,
334
334
  )
335
335
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
336
+ self.show_message_box(f"Cabrillo saved to: {filename}")
336
337
  except IOError as exception:
337
338
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
339
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
338
340
  return
339
341
 
340
342
 
@@ -333,8 +333,10 @@ def cabrillo(self):
333
333
  file=file_descriptor,
334
334
  )
335
335
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
336
+ self.show_message_box(f"Cabrillo saved to: {filename}")
336
337
  except IOError as exception:
337
338
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
339
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
338
340
  return
339
341
 
340
342
 
not1mm/plugins/cwt.py CHANGED
@@ -339,8 +339,10 @@ def cabrillo(self):
339
339
  file=file_descriptor,
340
340
  )
341
341
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
342
+ self.show_message_box(f"Cabrillo saved to: {filename}")
342
343
  except IOError as exception:
343
344
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
345
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
344
346
  return
345
347
 
346
348
 
not1mm/plugins/iaru_hf.py CHANGED
@@ -350,8 +350,10 @@ def cabrillo(self):
350
350
  file=file_descriptor,
351
351
  )
352
352
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
353
+ self.show_message_box(f"Cabrillo saved to: {filename}")
353
354
  except IOError as exception:
354
355
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
356
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
355
357
  return
356
358
 
357
359
 
not1mm/plugins/jidx_cw.py CHANGED
@@ -330,8 +330,10 @@ def cabrillo(self):
330
330
  file=file_descriptor,
331
331
  )
332
332
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
333
+ self.show_message_box(f"Cabrillo saved to: {filename}")
333
334
  except IOError as exception:
334
335
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
336
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
335
337
  return
336
338
 
337
339
 
not1mm/plugins/jidx_ph.py CHANGED
@@ -330,8 +330,10 @@ def cabrillo(self):
330
330
  file=file_descriptor,
331
331
  )
332
332
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
333
+ self.show_message_box(f"Cabrillo saved to: {filename}")
333
334
  except IOError as exception:
334
335
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
336
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
335
337
  return
336
338
 
337
339
 
not1mm/plugins/naqp_cw.py CHANGED
@@ -325,8 +325,10 @@ def cabrillo(self):
325
325
  file=file_descriptor,
326
326
  )
327
327
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
328
+ self.show_message_box(f"Cabrillo saved to: {filename}")
328
329
  except IOError as exception:
329
330
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
331
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
330
332
  return
331
333
 
332
334
 
@@ -325,8 +325,10 @@ def cabrillo(self):
325
325
  file=file_descriptor,
326
326
  )
327
327
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
328
+ self.show_message_box(f"Cabrillo saved to: {filename}")
328
329
  except IOError as exception:
329
330
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
331
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
330
332
  return
331
333
 
332
334
 
@@ -347,8 +347,10 @@ def cabrillo(self):
347
347
  file=file_descriptor,
348
348
  )
349
349
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
350
+ self.show_message_box(f"Cabrillo saved to: {filename}")
350
351
  except IOError as exception:
351
352
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
353
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
352
354
  return
353
355
 
354
356
 
@@ -325,8 +325,10 @@ def cabrillo(self):
325
325
  file=file_descriptor,
326
326
  )
327
327
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
328
+ self.show_message_box(f"Cabrillo saved to: {filename}")
328
329
  except IOError as exception:
329
330
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
331
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
330
332
  return
331
333
 
332
334
 
@@ -310,8 +310,10 @@ def cabrillo(self):
310
310
  file=file_descriptor,
311
311
  )
312
312
  print("END-OF-LOG:", end="\r\n", file=file_descriptor)
313
+ self.show_message_box(f"Cabrillo saved to: {filename}")
313
314
  except IOError as exception:
314
315
  logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
316
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
315
317
  return
316
318
 
317
319
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 24.3.9
3
+ Version: 24.3.19
4
4
  Summary: NOT1MM Logger
5
5
  Author-email: Michael Bridak <michael.bridak@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/mbridak/not1mm
@@ -149,6 +149,8 @@ I wish to thank those who've contributed to the project.
149
149
  - ARRL VHF January
150
150
  - ARRL VHF June
151
151
  - ARRL VHF September
152
+ - CQ 160 CW
153
+ - CQ 160 SSB
152
154
  - CQ WPX CW
153
155
  - CQ WPX SSB
154
156
  - CQ World Wide CW
@@ -166,6 +168,10 @@ I wish to thank those who've contributed to the project.
166
168
 
167
169
  ## Recent Changes
168
170
 
171
+ - [24-3-19] Removed some useless bloat causing slow interface on FreeBSD 13/14 and maybe others.
172
+ - [24-3-16] Add Save/Fail confirmation dialogs when saving ADIF of Cabrillo files.
173
+ - [24-3-15] Change 'CWR' to 'CW' in the ADIF output.
174
+ - [24-3-13] Added CQ 160 CW and SSB
169
175
  - [24-3-9] Marked calls in the bandmap window colored Blue, until worked.
170
176
  - [24-3-7] Merged PR from @arodland for faster fuzzy SCP lookups.
171
177
  - [24-3-2-1] Added marking stations on the bandmap to work later with CTRL-M.