not1mm 24.3.16__py3-none-any.whl → 24.3.21__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.
- not1mm/__main__.py +289 -125
- not1mm/bandmap.py +168 -163
- not1mm/checkwindow.py +55 -107
- not1mm/data/MASTER.SCP +1077 -749
- not1mm/data/bandmap.ui +4 -4
- not1mm/data/checkwindow.ui +9 -16
- not1mm/data/logwindow.ui +16 -11
- not1mm/data/main.ui +16 -6
- not1mm/data/vfo.ui +64 -52
- not1mm/data/vfo2.ui +84 -0
- not1mm/fsutils.py +38 -0
- not1mm/lib/about.py +4 -2
- not1mm/lib/cat_interface.py +1 -1
- not1mm/lib/cwinterface.py +1 -1
- not1mm/lib/database.py +4 -4
- not1mm/lib/edit_contact.py +2 -2
- not1mm/lib/edit_macro.py +2 -3
- not1mm/lib/edit_opon.py +2 -2
- not1mm/lib/edit_station.py +3 -3
- not1mm/lib/ham_utility.py +1 -1
- not1mm/lib/lookup.py +1 -1
- not1mm/lib/multicast.py +9 -4
- not1mm/lib/n1mm.py +1 -1
- not1mm/lib/new_contest.py +2 -2
- not1mm/lib/select_contest.py +2 -2
- not1mm/lib/settings.py +3 -4
- not1mm/lib/super_check_partial.py +6 -5
- not1mm/lib/version.py +1 -1
- not1mm/logwindow.py +60 -104
- not1mm/plugins/10_10_fall_cw.py +1 -1
- not1mm/plugins/10_10_spring_cw.py +1 -1
- not1mm/plugins/10_10_summer_phone.py +1 -1
- not1mm/plugins/10_10_winter_phone.py +1 -1
- not1mm/plugins/arrl_10m.py +1 -1
- not1mm/plugins/arrl_dx_cw.py +1 -1
- not1mm/plugins/arrl_dx_ssb.py +1 -1
- not1mm/plugins/arrl_field_day.py +1 -1
- not1mm/plugins/arrl_ss_cw.py +1 -1
- not1mm/plugins/arrl_ss_phone.py +1 -1
- not1mm/plugins/arrl_vhf_jan.py +1 -1
- not1mm/plugins/arrl_vhf_jun.py +1 -1
- not1mm/plugins/arrl_vhf_sep.py +1 -1
- not1mm/plugins/canada_day.py +1 -1
- not1mm/plugins/cq_160_cw.py +1 -1
- not1mm/plugins/cq_160_ssb.py +1 -1
- not1mm/plugins/cq_wpx_cw.py +1 -1
- not1mm/plugins/cq_wpx_ssb.py +1 -1
- not1mm/plugins/cq_ww_cw.py +1 -1
- not1mm/plugins/cq_ww_ssb.py +1 -1
- not1mm/plugins/cwt.py +1 -1
- not1mm/plugins/general_logging.py +1 -1
- not1mm/plugins/iaru_hf.py +1 -1
- not1mm/plugins/jidx_cw.py +1 -1
- not1mm/plugins/jidx_ph.py +1 -1
- not1mm/plugins/naqp_cw.py +1 -1
- not1mm/plugins/naqp_ssb.py +1 -1
- not1mm/plugins/phone_weekly_test.py +1 -1
- not1mm/plugins/stew_perry_topband.py +1 -1
- not1mm/plugins/winter_field_day.py +1 -1
- not1mm/vfo.py +77 -98
- {not1mm-24.3.16.dist-info → not1mm-24.3.21.dist-info}/METADATA +4 -1
- {not1mm-24.3.16.dist-info → not1mm-24.3.21.dist-info}/RECORD +68 -65
- testing/detectdark.py +35 -0
- testing/test.py +13 -11
- {not1mm-24.3.16.dist-info → not1mm-24.3.21.dist-info}/LICENSE +0 -0
- {not1mm-24.3.16.dist-info → not1mm-24.3.21.dist-info}/WHEEL +0 -0
- {not1mm-24.3.16.dist-info → not1mm-24.3.21.dist-info}/entry_points.txt +0 -0
- {not1mm-24.3.16.dist-info → not1mm-24.3.21.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
NOT1MM Logger
|
4
4
|
"""
|
5
5
|
# pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines, no-name-in-module
|
6
|
-
# pylint: disable=logging-fstring-interpolation
|
6
|
+
# pylint: disable=logging-fstring-interpolation, logging-not-lazy, line-too-long
|
7
7
|
|
8
8
|
# alt cluster hamqth.com 7300
|
9
9
|
|
@@ -11,12 +11,14 @@ import datetime
|
|
11
11
|
import importlib
|
12
12
|
import locale
|
13
13
|
import logging
|
14
|
+
from logging.handlers import RotatingFileHandler
|
14
15
|
import os
|
15
16
|
|
16
17
|
import platform
|
17
18
|
import re
|
18
19
|
import socket
|
19
|
-
|
20
|
+
|
21
|
+
# import subprocess
|
20
22
|
import sys
|
21
23
|
import threading
|
22
24
|
import uuid
|
@@ -32,7 +34,7 @@ import soundfile as sf
|
|
32
34
|
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
33
35
|
from PyQt5.QtCore import QDir, Qt
|
34
36
|
from PyQt5.QtGui import QFontDatabase
|
35
|
-
from PyQt5.QtWidgets import QFileDialog
|
37
|
+
from PyQt5.QtWidgets import QFileDialog, QDockWidget
|
36
38
|
|
37
39
|
from not1mm.lib.about import About
|
38
40
|
from not1mm.lib.cat_interface import CAT
|
@@ -62,31 +64,15 @@ from not1mm.lib.settings import Settings
|
|
62
64
|
from not1mm.lib.version import __version__
|
63
65
|
from not1mm.lib.versiontest import VersionTest
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
DATA_PATH = os.environ.get("XDG_DATA_HOME", str(Path.home() / ".local" / "share"))
|
71
|
-
DATA_PATH += "/not1mm"
|
72
|
-
|
73
|
-
try:
|
74
|
-
os.mkdir(DATA_PATH)
|
75
|
-
except FileExistsError:
|
76
|
-
...
|
77
|
-
|
78
|
-
CONFIG_PATH = os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config"))
|
79
|
-
CONFIG_PATH += "/not1mm"
|
80
|
-
|
81
|
-
try:
|
82
|
-
os.mkdir(CONFIG_PATH)
|
83
|
-
except FileExistsError:
|
84
|
-
...
|
85
|
-
|
67
|
+
import not1mm.fsutils as fsutils
|
68
|
+
from not1mm.logwindow import LogWindow
|
69
|
+
from not1mm.checkwindow import CheckWindow
|
70
|
+
from not1mm.bandmap import BandMapWindow
|
71
|
+
from not1mm.vfo import VfoWindow
|
86
72
|
|
87
73
|
CTYFILE = {}
|
88
74
|
|
89
|
-
with open(
|
75
|
+
with open(fsutils.APP_DATA_PATH / "cty.json", "rt", encoding="utf-8") as c_file:
|
90
76
|
CTYFILE = loads(c_file.read())
|
91
77
|
|
92
78
|
poll_time = datetime.datetime.now()
|
@@ -137,7 +123,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
137
123
|
"contest": "",
|
138
124
|
"multicast_group": "239.1.1.1",
|
139
125
|
"multicast_port": 2239,
|
140
|
-
"interface_ip": "
|
126
|
+
"interface_ip": "127.0.0.1",
|
141
127
|
"send_n1mm_packets": False,
|
142
128
|
"n1mm_station_name": "20M CW Tent",
|
143
129
|
"n1mm_operator": "Bernie",
|
@@ -184,24 +170,33 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
184
170
|
contest_dialog = None
|
185
171
|
configuration_dialog = None
|
186
172
|
opon_dialog = None
|
187
|
-
dbname =
|
173
|
+
dbname = fsutils.USER_DATA_PATH, "/ham.db"
|
188
174
|
radio_state = {}
|
189
175
|
rig_control = None
|
190
176
|
worked_list = {}
|
191
177
|
cw_entry_visible = False
|
192
178
|
last_focus = None
|
193
179
|
oldtext = ""
|
180
|
+
text_color = Qt.black
|
181
|
+
current_palette = None
|
182
|
+
|
183
|
+
log_window = None
|
184
|
+
check_window = None
|
185
|
+
bandmap_window = None
|
186
|
+
vfo_window = None
|
194
187
|
|
195
188
|
def __init__(self, *args, **kwargs):
|
196
189
|
super().__init__(*args, **kwargs)
|
197
190
|
logger.info("MainWindow: __init__")
|
198
|
-
|
191
|
+
self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)
|
192
|
+
self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)
|
193
|
+
data_path = fsutils.APP_DATA_PATH / "main.ui"
|
199
194
|
uic.loadUi(data_path, self)
|
200
195
|
self.cw_entry.hide()
|
201
196
|
self.leftdot.hide()
|
202
197
|
self.rightdot.hide()
|
203
198
|
self.n1mm = N1MM()
|
204
|
-
self.mscp = SCP(
|
199
|
+
self.mscp = SCP(fsutils.APP_DATA_PATH)
|
205
200
|
self.next_field = self.other_2
|
206
201
|
self.dupe_indicator.hide()
|
207
202
|
self.cw_speed.valueChanged.connect(self.cwspeed_spinbox_changed)
|
@@ -210,6 +205,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
210
205
|
self.cw_entry.returnPressed.connect(self.toggle_cw_entry)
|
211
206
|
|
212
207
|
self.actionCW_Macros.triggered.connect(self.cw_macros_state_changed)
|
208
|
+
self.actionDark_Mode_2.triggered.connect(self.dark_mode_state_changed)
|
213
209
|
self.actionCommand_Buttons.triggered.connect(self.command_buttons_state_change)
|
214
210
|
self.actionLog_Window.triggered.connect(self.launch_log_window)
|
215
211
|
self.actionBandmap.triggered.connect(self.launch_bandmap_window)
|
@@ -255,15 +251,15 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
255
251
|
|
256
252
|
self.sent.setText("59")
|
257
253
|
self.receive.setText("59")
|
258
|
-
icon_path =
|
259
|
-
self.greendot = QtGui.QPixmap(icon_path
|
260
|
-
self.reddot = QtGui.QPixmap(icon_path
|
254
|
+
icon_path = fsutils.APP_DATA_PATH
|
255
|
+
self.greendot = QtGui.QPixmap(str(icon_path / "greendot.png"))
|
256
|
+
self.reddot = QtGui.QPixmap(str(icon_path / "reddot.png"))
|
261
257
|
self.leftdot.setPixmap(self.greendot)
|
262
258
|
self.rightdot.setPixmap(self.reddot)
|
263
259
|
|
264
|
-
self.radio_grey = QtGui.QPixmap(icon_path
|
265
|
-
self.radio_red = QtGui.QPixmap(icon_path
|
266
|
-
self.radio_green = QtGui.QPixmap(icon_path
|
260
|
+
self.radio_grey = QtGui.QPixmap(str(icon_path / "radio_grey.png"))
|
261
|
+
self.radio_red = QtGui.QPixmap(str(icon_path / "radio_red.png"))
|
262
|
+
self.radio_green = QtGui.QPixmap(str(icon_path / "radio_green.png"))
|
267
263
|
self.radio_icon.setPixmap(self.radio_grey)
|
268
264
|
|
269
265
|
self.F1.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
@@ -461,9 +457,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
461
457
|
"RTTY": self.band_indicators_rtty,
|
462
458
|
}
|
463
459
|
|
460
|
+
self.setWindowIcon(
|
461
|
+
QtGui.QIcon(str(fsutils.APP_DATA_PATH / "k6gte.not1mm-64.png"))
|
462
|
+
)
|
464
463
|
self.readpreferences()
|
465
|
-
self.dbname =
|
466
|
-
|
464
|
+
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
465
|
+
"current_database", "ham.db"
|
466
|
+
)
|
467
|
+
self.database = DataBase(self.dbname, fsutils.APP_DATA_PATH)
|
467
468
|
self.station = self.database.fetch_station()
|
468
469
|
if self.station is None:
|
469
470
|
self.station = {}
|
@@ -480,11 +481,80 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
480
481
|
if self.pref.get("contest"):
|
481
482
|
self.load_contest()
|
482
483
|
|
483
|
-
if
|
484
|
-
|
485
|
-
|
486
|
-
|
484
|
+
if not DEBUG_ENABLED:
|
485
|
+
if VersionTest(__version__).test():
|
486
|
+
self.show_message_box(
|
487
|
+
"There is a newer version of not1mm available.\n"
|
488
|
+
"You can udate to the current version by using:\npip install -U not1mm"
|
489
|
+
)
|
490
|
+
|
491
|
+
def setDarkMode(self, dark):
|
492
|
+
"""testing"""
|
493
|
+
|
494
|
+
logger.debug(f"Dark mode set to: {dark}")
|
495
|
+
|
496
|
+
cmd = {}
|
497
|
+
cmd["cmd"] = "DARKMODE"
|
498
|
+
cmd["state"] = dark
|
499
|
+
cmd["station"] = platform.node()
|
500
|
+
self.multicast_interface.send_as_json(cmd)
|
501
|
+
|
502
|
+
if dark:
|
503
|
+
darkPalette = QtGui.QPalette()
|
504
|
+
darkColor = QtGui.QColor(45, 45, 45)
|
505
|
+
|
506
|
+
disabledColor = QtGui.QColor(127, 127, 127)
|
507
|
+
darkPalette.setColor(QtGui.QPalette.Window, darkColor)
|
508
|
+
darkPalette.setColor(QtGui.QPalette.WindowText, Qt.white)
|
509
|
+
darkPalette.setColor(QtGui.QPalette.Base, QtGui.QColor(18, 18, 18))
|
510
|
+
darkPalette.setColor(QtGui.QPalette.AlternateBase, darkColor)
|
511
|
+
darkPalette.setColor(QtGui.QPalette.Text, Qt.white)
|
512
|
+
darkPalette.setColor(
|
513
|
+
QtGui.QPalette.Disabled, QtGui.QPalette.Text, disabledColor
|
514
|
+
)
|
515
|
+
darkPalette.setColor(QtGui.QPalette.Button, darkColor)
|
516
|
+
darkPalette.setColor(QtGui.QPalette.ButtonText, Qt.white)
|
517
|
+
darkPalette.setColor(
|
518
|
+
QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, disabledColor
|
487
519
|
)
|
520
|
+
darkPalette.setColor(QtGui.QPalette.BrightText, Qt.red)
|
521
|
+
darkPalette.setColor(QtGui.QPalette.Link, QtGui.QColor(42, 130, 218))
|
522
|
+
darkPalette.setColor(QtGui.QPalette.Highlight, QtGui.QColor(42, 130, 218))
|
523
|
+
darkPalette.setColor(QtGui.QPalette.HighlightedText, Qt.black)
|
524
|
+
darkPalette.setColor(
|
525
|
+
QtGui.QPalette.Disabled, QtGui.QPalette.HighlightedText, disabledColor
|
526
|
+
)
|
527
|
+
self.current_palette = darkPalette
|
528
|
+
self.setPalette(darkPalette)
|
529
|
+
self.text_color = Qt.white
|
530
|
+
self.menuFile.setPalette(darkPalette)
|
531
|
+
self.menuHelp.setPalette(darkPalette)
|
532
|
+
self.menuOther.setPalette(darkPalette)
|
533
|
+
self.menuView.setPalette(darkPalette)
|
534
|
+
self.menuWindow.setPalette(darkPalette)
|
535
|
+
self.callsign.setPalette(darkPalette)
|
536
|
+
self.sent.setPalette(darkPalette)
|
537
|
+
self.receive.setPalette(darkPalette)
|
538
|
+
self.other_1.setPalette(darkPalette)
|
539
|
+
self.other_2.setPalette(darkPalette)
|
540
|
+
self.cw_entry.setPalette(darkPalette)
|
541
|
+
|
542
|
+
else:
|
543
|
+
palette = self.style().standardPalette()
|
544
|
+
self.current_palette = palette
|
545
|
+
self.setPalette(palette)
|
546
|
+
self.menuFile.setPalette(palette)
|
547
|
+
self.menuHelp.setPalette(palette)
|
548
|
+
self.menuOther.setPalette(palette)
|
549
|
+
self.menuView.setPalette(palette)
|
550
|
+
self.menuWindow.setPalette(palette)
|
551
|
+
self.callsign.setPalette(palette)
|
552
|
+
self.sent.setPalette(palette)
|
553
|
+
self.receive.setPalette(palette)
|
554
|
+
self.other_1.setPalette(palette)
|
555
|
+
self.other_2.setPalette(palette)
|
556
|
+
self.cw_entry.setPalette(palette)
|
557
|
+
self.text_color = Qt.black
|
488
558
|
|
489
559
|
def set_radio_icon(self, state: int) -> None:
|
490
560
|
"""
|
@@ -624,6 +694,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
624
694
|
"""
|
625
695
|
|
626
696
|
message_box = QtWidgets.QMessageBox()
|
697
|
+
if self.current_palette:
|
698
|
+
message_box.setPalette(self.current_palette)
|
627
699
|
message_box.setIcon(QtWidgets.QMessageBox.Information)
|
628
700
|
message_box.setText(message)
|
629
701
|
message_box.setWindowTitle("Information")
|
@@ -643,9 +715,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
643
715
|
None
|
644
716
|
"""
|
645
717
|
|
646
|
-
self.about_dialog = About(
|
718
|
+
self.about_dialog = About(fsutils.APP_DATA_PATH)
|
719
|
+
if self.current_palette:
|
720
|
+
self.about_dialog.setPalette(self.current_palette)
|
721
|
+
|
647
722
|
self.about_dialog.donors.setSource(
|
648
|
-
QtCore.QUrl.fromLocalFile(
|
723
|
+
QtCore.QUrl.fromLocalFile(f"{fsutils.APP_DATA_PATH / 'donors.html'}")
|
649
724
|
)
|
650
725
|
self.about_dialog.open()
|
651
726
|
|
@@ -662,11 +737,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
662
737
|
None
|
663
738
|
"""
|
664
739
|
|
665
|
-
self.about_dialog = About(
|
740
|
+
self.about_dialog = About(fsutils.APP_DATA_PATH)
|
741
|
+
if self.current_palette:
|
742
|
+
self.about_dialog.setPalette(self.current_palette)
|
743
|
+
|
666
744
|
self.about_dialog.setWindowTitle("Help")
|
667
745
|
self.about_dialog.setGeometry(0, 0, 800, 600)
|
668
746
|
self.about_dialog.donors.setSource(
|
669
|
-
QtCore.QUrl.fromLocalFile(
|
747
|
+
QtCore.QUrl.fromLocalFile(str(fsutils.APP_DATA_PATH / "not1mm.html"))
|
670
748
|
)
|
671
749
|
self.about_dialog.open()
|
672
750
|
|
@@ -703,7 +781,9 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
703
781
|
None
|
704
782
|
"""
|
705
783
|
|
706
|
-
self.configuration_dialog = Settings(
|
784
|
+
self.configuration_dialog = Settings(fsutils.APP_DATA_PATH, self.pref)
|
785
|
+
if self.current_palette:
|
786
|
+
self.configuration_dialog.setPalette(self.current_palette)
|
707
787
|
self.configuration_dialog.usehamdb_radioButton.hide()
|
708
788
|
self.configuration_dialog.show()
|
709
789
|
self.configuration_dialog.accepted.connect(self.edit_configuration_return)
|
@@ -723,7 +803,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
723
803
|
|
724
804
|
self.configuration_dialog.save_changes()
|
725
805
|
self.write_preference()
|
726
|
-
logger.debug("%s", f"{self.pref}")
|
806
|
+
# logger.debug("%s", f"{self.pref}")
|
727
807
|
self.readpreferences()
|
728
808
|
|
729
809
|
def new_database(self) -> None:
|
@@ -743,10 +823,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
743
823
|
if filename:
|
744
824
|
if filename[-3:] != ".db":
|
745
825
|
filename += ".db"
|
746
|
-
self.pref["current_database"] =
|
826
|
+
self.pref["current_database"] = os.path.basename(filename)
|
747
827
|
self.write_preference()
|
748
|
-
self.dbname =
|
749
|
-
|
828
|
+
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
829
|
+
"current_database", "ham.db"
|
830
|
+
)
|
831
|
+
self.database = DataBase(self.dbname, fsutils.APP_DATA_PATH)
|
750
832
|
self.contact = self.database.empty_contact
|
751
833
|
self.station = self.database.fetch_station()
|
752
834
|
if self.station is None:
|
@@ -775,10 +857,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
775
857
|
|
776
858
|
filename = self.filepicker("open")
|
777
859
|
if filename:
|
778
|
-
self.pref["current_database"] =
|
860
|
+
self.pref["current_database"] = os.path.basename(filename)
|
779
861
|
self.write_preference()
|
780
|
-
self.dbname =
|
781
|
-
|
862
|
+
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
863
|
+
"current_database", "ham.db"
|
864
|
+
)
|
865
|
+
self.database = DataBase(self.dbname, fsutils.MODULE_PATH)
|
782
866
|
self.contact = self.database.empty_contact
|
783
867
|
self.station = self.database.fetch_station()
|
784
868
|
if self.station is None:
|
@@ -814,7 +898,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
814
898
|
logger.debug("%s", f"{contests}")
|
815
899
|
|
816
900
|
if contests:
|
817
|
-
self.contest_dialog = SelectContest(
|
901
|
+
self.contest_dialog = SelectContest(fsutils.APP_DATA_PATH)
|
902
|
+
if self.current_palette:
|
903
|
+
self.contest_dialog.setPalette(self.current_palette)
|
904
|
+
|
818
905
|
self.contest_dialog.contest_list.setRowCount(0)
|
819
906
|
self.contest_dialog.contest_list.setColumnCount(4)
|
820
907
|
self.contest_dialog.contest_list.verticalHeader().setVisible(False)
|
@@ -912,7 +999,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
912
999
|
return
|
913
1000
|
if self.contest_settings is None:
|
914
1001
|
return
|
915
|
-
|
1002
|
+
|
1003
|
+
self.contest_dialog = NewContest(fsutils.APP_DATA_PATH)
|
1004
|
+
if self.current_palette:
|
1005
|
+
self.contest_dialog.setPalette(self.current_palette)
|
1006
|
+
self.contest_dialog.exchange.setPalette(self.current_palette)
|
1007
|
+
self.contest_dialog.operators.setPalette(self.current_palette)
|
1008
|
+
self.contest_dialog.contest.setPalette(self.current_palette)
|
1009
|
+
|
916
1010
|
self.contest_dialog.setWindowTitle("Edit Contest")
|
917
1011
|
self.contest_dialog.title.setText("")
|
918
1012
|
self.contest_dialog.accepted.connect(self.save_edited_contest)
|
@@ -1078,7 +1172,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1078
1172
|
"""
|
1079
1173
|
|
1080
1174
|
try:
|
1081
|
-
cty = notctyparser.BigCty(
|
1175
|
+
cty = notctyparser.BigCty(fsutils.APP_DATA_PATH / "cty.json")
|
1082
1176
|
update_available = cty.check_update()
|
1083
1177
|
except (AttributeError, ValueError, locale.Error) as the_error:
|
1084
1178
|
logger.debug("cty parser returned an error: %s", the_error)
|
@@ -1092,10 +1186,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1092
1186
|
logger.debug("cty parser returned an error: %s", the_error)
|
1093
1187
|
return
|
1094
1188
|
if updated:
|
1095
|
-
cty.dump(
|
1189
|
+
cty.dump(fsutils.APP_DATA_PATH / "cty.json")
|
1096
1190
|
self.show_message_box("cty file updated.")
|
1097
1191
|
with open(
|
1098
|
-
|
1192
|
+
fsutils.APP_DATA_PATH / "cty.json", "rt", encoding="utf-8"
|
1099
1193
|
) as ctyfile:
|
1100
1194
|
globals()["CTYFILE"] = loads(ctyfile.read())
|
1101
1195
|
else:
|
@@ -1198,7 +1292,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1198
1292
|
file, _ = QFileDialog.getSaveFileName(
|
1199
1293
|
self,
|
1200
1294
|
"Choose a Database",
|
1201
|
-
|
1295
|
+
str(fsutils.USER_DATA_PATH),
|
1202
1296
|
"Database (*.db)",
|
1203
1297
|
options=options,
|
1204
1298
|
)
|
@@ -1206,7 +1300,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1206
1300
|
file, _ = QFileDialog.getOpenFileName(
|
1207
1301
|
self,
|
1208
1302
|
"Choose a Database",
|
1209
|
-
|
1303
|
+
str(fsutils.USER_DATA_PATH),
|
1210
1304
|
"Database (*.db)",
|
1211
1305
|
options=options,
|
1212
1306
|
)
|
@@ -1218,24 +1312,38 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1218
1312
|
self.clearinputs()
|
1219
1313
|
|
1220
1314
|
def launch_log_window(self) -> None:
|
1221
|
-
"""
|
1222
|
-
if not
|
1223
|
-
|
1315
|
+
"""Launch the log window"""
|
1316
|
+
if not self.log_window:
|
1317
|
+
log_widget = LogWindow()
|
1318
|
+
self.log_window = QDockWidget(log_widget.property("windowTitle"), self)
|
1319
|
+
self.log_window.setWidget(log_widget)
|
1320
|
+
self.addDockWidget(Qt.BottomDockWidgetArea, self.log_window)
|
1321
|
+
self.log_window.show()
|
1224
1322
|
|
1225
1323
|
def launch_bandmap_window(self) -> None:
|
1226
|
-
"""
|
1227
|
-
if not
|
1228
|
-
|
1324
|
+
"""Launch the bandmap window"""
|
1325
|
+
if not self.bandmap_window:
|
1326
|
+
self.bandmap_window = BandMapWindow()
|
1327
|
+
self.addDockWidget(Qt.RightDockWidgetArea, self.bandmap_window)
|
1328
|
+
self.bandmap_window.show()
|
1229
1329
|
|
1230
1330
|
def launch_check_window(self) -> None:
|
1231
|
-
"""
|
1232
|
-
if not
|
1233
|
-
|
1331
|
+
"""Launch the check window"""
|
1332
|
+
if not self.check_window:
|
1333
|
+
check_widget = CheckWindow()
|
1334
|
+
self.check_window = QDockWidget(check_widget.property("windowTitle"), self)
|
1335
|
+
self.check_window.setWidget(check_widget)
|
1336
|
+
self.addDockWidget(Qt.RightDockWidgetArea, self.check_window)
|
1337
|
+
self.check_window.show()
|
1234
1338
|
|
1235
1339
|
def launch_vfo(self) -> None:
|
1236
|
-
"""
|
1237
|
-
if not
|
1238
|
-
|
1340
|
+
"""Launch the VFO window"""
|
1341
|
+
if not self.vfo_window:
|
1342
|
+
vfo_widget = VfoWindow()
|
1343
|
+
self.vfo_window = QDockWidget(vfo_widget.property("windowTitle"), self)
|
1344
|
+
self.vfo_window.setWidget(vfo_widget)
|
1345
|
+
self.addDockWidget(Qt.RightDockWidgetArea, self.vfo_window)
|
1346
|
+
self.vfo_window.show()
|
1239
1347
|
|
1240
1348
|
def clear_band_indicators(self) -> None:
|
1241
1349
|
"""
|
@@ -1252,7 +1360,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1252
1360
|
for _, indicators in self.all_mode_indicators.items():
|
1253
1361
|
for _, indicator in indicators.items():
|
1254
1362
|
indicator.setFrameShape(QtWidgets.QFrame.NoFrame)
|
1255
|
-
|
1363
|
+
if self.text_color == Qt.black:
|
1364
|
+
indicator.setStyleSheet(
|
1365
|
+
"font-family: JetBrains Mono; color: black;"
|
1366
|
+
)
|
1367
|
+
else:
|
1368
|
+
indicator.setStyleSheet("font-family: JetBrains Mono; color: white")
|
1256
1369
|
|
1257
1370
|
def set_band_indicator(self, band: str) -> None:
|
1258
1371
|
"""
|
@@ -1739,7 +1852,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1739
1852
|
"""
|
1740
1853
|
|
1741
1854
|
logger.debug("New contest Dialog")
|
1742
|
-
|
1855
|
+
|
1856
|
+
self.contest_dialog = NewContest(fsutils.APP_DATA_PATH)
|
1857
|
+
if self.current_palette:
|
1858
|
+
self.contest_dialog.setPalette(self.current_palette)
|
1859
|
+
self.contest_dialog.exchange.setPalette(self.current_palette)
|
1860
|
+
self.contest_dialog.operators.setPalette(self.current_palette)
|
1861
|
+
|
1743
1862
|
self.contest_dialog.accepted.connect(self.save_contest)
|
1744
1863
|
self.contest_dialog.dateTimeEdit.setDate(QtCore.QDate.currentDate())
|
1745
1864
|
self.contest_dialog.dateTimeEdit.setCalendarPopup(True)
|
@@ -1804,7 +1923,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1804
1923
|
"""
|
1805
1924
|
|
1806
1925
|
logger.debug("Station Settings selected")
|
1807
|
-
|
1926
|
+
|
1927
|
+
self.settings_dialog = EditStation(fsutils.APP_DATA_PATH)
|
1928
|
+
if self.current_palette:
|
1929
|
+
self.settings_dialog.setPalette(self.current_palette)
|
1930
|
+
|
1808
1931
|
self.settings_dialog.accepted.connect(self.save_settings)
|
1809
1932
|
self.settings_dialog.Call.setText(self.station.get("Call", ""))
|
1810
1933
|
self.settings_dialog.Name.setText(self.station.get("Name", ""))
|
@@ -1892,7 +2015,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1892
2015
|
None
|
1893
2016
|
"""
|
1894
2017
|
|
1895
|
-
self.edit_macro_dialog = EditMacro(function_key,
|
2018
|
+
self.edit_macro_dialog = EditMacro(function_key, fsutils.APP_DATA_PATH)
|
2019
|
+
|
2020
|
+
if self.current_palette:
|
2021
|
+
self.edit_macro_dialog.setPalette(self.current_palette)
|
2022
|
+
|
1896
2023
|
self.edit_macro_dialog.accepted.connect(self.edited_macro)
|
1897
2024
|
self.edit_macro_dialog.open()
|
1898
2025
|
|
@@ -1965,7 +2092,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1965
2092
|
"""
|
1966
2093
|
|
1967
2094
|
logger.debug("Voicing: %s", the_string)
|
1968
|
-
op_path =
|
2095
|
+
op_path = fsutils.USER_DATA_PATH / self.current_op
|
1969
2096
|
if "[" in the_string:
|
1970
2097
|
sub_string = the_string.strip("[]").lower()
|
1971
2098
|
filename = f"{str(op_path)}/{sub_string}.wav"
|
@@ -2093,11 +2220,9 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2093
2220
|
|
2094
2221
|
logger.debug("writepreferences")
|
2095
2222
|
try:
|
2096
|
-
with open(
|
2097
|
-
CONFIG_PATH + "/not1mm.json", "wt", encoding="utf-8"
|
2098
|
-
) as file_descriptor:
|
2223
|
+
with open(fsutils.CONFIG_FILE, "wt", encoding="utf-8") as file_descriptor:
|
2099
2224
|
file_descriptor.write(dumps(self.pref, indent=4))
|
2100
|
-
logger.info("writing: %s", self.pref)
|
2225
|
+
# logger.info("writing: %s", self.pref)
|
2101
2226
|
except IOError as exception:
|
2102
2227
|
logger.critical("writepreferences: %s", exception)
|
2103
2228
|
|
@@ -2116,16 +2241,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2116
2241
|
|
2117
2242
|
logger.debug("readpreferences")
|
2118
2243
|
try:
|
2119
|
-
if os.path.exists(
|
2244
|
+
if os.path.exists(fsutils.CONFIG_FILE):
|
2120
2245
|
with open(
|
2121
|
-
|
2246
|
+
fsutils.CONFIG_FILE, "rt", encoding="utf-8"
|
2122
2247
|
) as file_descriptor:
|
2123
2248
|
self.pref = loads(file_descriptor.read())
|
2124
2249
|
logger.info("%s", self.pref)
|
2125
2250
|
else:
|
2126
2251
|
logger.info("No preference file. Writing preference.")
|
2127
2252
|
with open(
|
2128
|
-
|
2253
|
+
fsutils.CONFIG_FILE, "wt", encoding="utf-8"
|
2129
2254
|
) as file_descriptor:
|
2130
2255
|
self.pref = self.pref_ref.copy()
|
2131
2256
|
file_descriptor.write(dumps(self.pref, indent=4))
|
@@ -2173,6 +2298,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2173
2298
|
)
|
2174
2299
|
self.multicast_interface.ready_read_connect(self.watch_udp)
|
2175
2300
|
|
2301
|
+
if self.pref.get("darkmode"):
|
2302
|
+
self.actionDark_Mode_2.setChecked(True)
|
2303
|
+
self.setDarkMode(True)
|
2304
|
+
else:
|
2305
|
+
self.setDarkMode(False)
|
2306
|
+
self.actionDark_Mode_2.setChecked(False)
|
2307
|
+
|
2176
2308
|
self.rig_control = None
|
2177
2309
|
|
2178
2310
|
if self.pref.get("useflrig", False):
|
@@ -2300,6 +2432,24 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2300
2432
|
cmd["worked"] = result
|
2301
2433
|
self.multicast_interface.send_as_json(cmd)
|
2302
2434
|
|
2435
|
+
if (
|
2436
|
+
json_data.get("cmd", "") == "GETCONTESTSTATUS"
|
2437
|
+
and json_data.get("station", "") == platform.node()
|
2438
|
+
):
|
2439
|
+
cmd = {
|
2440
|
+
"cmd": "CONTESTSTATUS",
|
2441
|
+
"station": platform.node(),
|
2442
|
+
"contest": self.contest_settings,
|
2443
|
+
"operator": self.current_op,
|
2444
|
+
}
|
2445
|
+
self.multicast_interface.send_as_json(cmd)
|
2446
|
+
|
2447
|
+
def dark_mode_state_changed(self) -> None:
|
2448
|
+
"""Called when the Dark Mode menu state is changed."""
|
2449
|
+
self.pref["darkmode"] = self.actionDark_Mode_2.isChecked()
|
2450
|
+
self.write_preference()
|
2451
|
+
self.setDarkMode(self.actionDark_Mode_2.isChecked())
|
2452
|
+
|
2303
2453
|
def cw_macros_state_changed(self) -> None:
|
2304
2454
|
"""
|
2305
2455
|
Menu item to show/hide macro buttons.
|
@@ -2478,8 +2628,6 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2478
2628
|
stripped_text = text.strip().replace(" ", "")
|
2479
2629
|
self.callsign.setText(stripped_text)
|
2480
2630
|
self.callsign.setCursorPosition(position)
|
2481
|
-
results = self.mscp.super_check(stripped_text)
|
2482
|
-
logger.debug(f"{results}")
|
2483
2631
|
|
2484
2632
|
if " " in text:
|
2485
2633
|
if stripped_text == "CW":
|
@@ -2771,7 +2919,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2771
2919
|
None
|
2772
2920
|
"""
|
2773
2921
|
|
2774
|
-
self.opon_dialog = OpOn(
|
2922
|
+
self.opon_dialog = OpOn(fsutils.APP_DATA_PATH)
|
2923
|
+
|
2924
|
+
if self.current_palette:
|
2925
|
+
self.opon_dialog.setPalette(self.current_palette)
|
2926
|
+
|
2775
2927
|
self.opon_dialog.accepted.connect(self.new_op)
|
2776
2928
|
self.opon_dialog.open()
|
2777
2929
|
|
@@ -2810,13 +2962,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2810
2962
|
"""
|
2811
2963
|
|
2812
2964
|
if self.current_op:
|
2813
|
-
op_path =
|
2965
|
+
op_path = fsutils.USER_DATA_PATH / self.current_op
|
2814
2966
|
logger.debug("op_path: %s", str(op_path))
|
2815
2967
|
if op_path.is_dir() is False:
|
2816
2968
|
logger.debug("Creating Op Directory: %s", str(op_path))
|
2817
2969
|
os.mkdir(str(op_path))
|
2818
2970
|
if op_path.is_dir():
|
2819
|
-
source_path =
|
2971
|
+
source_path = fsutils.APP_DATA_PATH / "phonetics"
|
2820
2972
|
logger.debug("source_path: %s", str(source_path))
|
2821
2973
|
for child in source_path.iterdir():
|
2822
2974
|
destination_file = op_path / child.name
|
@@ -2913,13 +3065,20 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2913
3065
|
None
|
2914
3066
|
"""
|
2915
3067
|
if self.radio_state.get("mode") == "CW":
|
2916
|
-
macro_file = "
|
3068
|
+
macro_file = "cwmacros.txt"
|
2917
3069
|
else:
|
2918
|
-
macro_file = "
|
2919
|
-
if not
|
3070
|
+
macro_file = "ssbmacros.txt"
|
3071
|
+
if not (fsutils.USER_DATA_PATH / macro_file).exists():
|
2920
3072
|
logger.debug("read_cw_macros: copying default macro file.")
|
2921
|
-
copyfile(
|
2922
|
-
|
3073
|
+
copyfile(
|
3074
|
+
fsutils.APP_DATA_PATH / macro_file, fsutils.USER_DATA_PATH / macro_file
|
3075
|
+
)
|
3076
|
+
try:
|
3077
|
+
fsutils.openFileWithOS(fsutils.USER_DATA_PATH / macro_file)
|
3078
|
+
except:
|
3079
|
+
logger.exception(
|
3080
|
+
f"Could not open file {fsutils.USER_DATA_PATH / macro_file}"
|
3081
|
+
)
|
2923
3082
|
|
2924
3083
|
def read_cw_macros(self) -> None:
|
2925
3084
|
"""
|
@@ -2929,14 +3088,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2929
3088
|
"""
|
2930
3089
|
|
2931
3090
|
if self.radio_state.get("mode") == "CW":
|
2932
|
-
macro_file = "
|
3091
|
+
macro_file = "cwmacros.txt"
|
2933
3092
|
else:
|
2934
|
-
macro_file = "
|
3093
|
+
macro_file = "ssbmacros.txt"
|
2935
3094
|
|
2936
|
-
if not
|
3095
|
+
if not (fsutils.USER_DATA_PATH / macro_file).exists():
|
2937
3096
|
logger.debug("read_cw_macros: copying default macro file.")
|
2938
|
-
copyfile(
|
2939
|
-
|
3097
|
+
copyfile(
|
3098
|
+
fsutils.APP_DATA_PATH / macro_file, fsutils.USER_DATA_PATH / macro_file
|
3099
|
+
)
|
3100
|
+
with open(
|
3101
|
+
fsutils.USER_DATA_PATH / macro_file, "r", encoding="utf-8"
|
3102
|
+
) as file_descriptor:
|
2940
3103
|
for line in file_descriptor:
|
2941
3104
|
try:
|
2942
3105
|
mode, fkey, buttonname, cwtext = line.split("|")
|
@@ -3045,17 +3208,19 @@ def install_icons() -> None:
|
|
3045
3208
|
if sys.platform == "linux":
|
3046
3209
|
os.system(
|
3047
3210
|
"xdg-icon-resource install --size 32 --context apps --mode user "
|
3048
|
-
f"{
|
3211
|
+
f"{fsutils.MODULE_PATH}/data/k6gte.not1mm-32.png k6gte-not1mm"
|
3049
3212
|
)
|
3050
3213
|
os.system(
|
3051
3214
|
"xdg-icon-resource install --size 64 --context apps --mode user "
|
3052
|
-
f"{
|
3215
|
+
f"{fsutils.MODULE_PATH}/data/k6gte.not1mm-64.png k6gte-not1mm"
|
3053
3216
|
)
|
3054
3217
|
os.system(
|
3055
3218
|
"xdg-icon-resource install --size 128 --context apps --mode user "
|
3056
|
-
f"{
|
3219
|
+
f"{fsutils.MODULE_PATH}/data/k6gte.not1mm-128.png k6gte-not1mm"
|
3220
|
+
)
|
3221
|
+
os.system(
|
3222
|
+
f"xdg-desktop-menu install {fsutils.MODULE_PATH}/data/k6gte-not1mm.desktop"
|
3057
3223
|
)
|
3058
|
-
os.system(f"xdg-desktop-menu install {WORKING_PATH}/data/k6gte-not1mm.desktop")
|
3059
3224
|
|
3060
3225
|
|
3061
3226
|
def doimp(modname) -> object:
|
@@ -3081,36 +3246,35 @@ def run() -> None:
|
|
3081
3246
|
"""
|
3082
3247
|
Main Entry
|
3083
3248
|
"""
|
3249
|
+
logger.debug(
|
3250
|
+
f"Resolved OS file system paths: MODULE_PATH {fsutils.MODULE_PATH}, USER_DATA_PATH {fsutils.USER_DATA_PATH}, CONFIG_PATH {fsutils.CONFIG_PATH}"
|
3251
|
+
)
|
3084
3252
|
install_icons()
|
3085
3253
|
timer.start(250)
|
3086
3254
|
sys.exit(app.exec())
|
3087
3255
|
|
3088
3256
|
|
3089
|
-
|
3090
|
-
handler = logging.StreamHandler()
|
3091
|
-
formatter = logging.Formatter(
|
3092
|
-
datefmt="%H:%M:%S",
|
3093
|
-
fmt="[%(asctime)s] %(levelname)s %(module)s - %(funcName)s Line %(lineno)d: %(message)s",
|
3094
|
-
)
|
3095
|
-
handler.setFormatter(formatter)
|
3096
|
-
logger.addHandler(handler)
|
3097
|
-
|
3098
|
-
BETA_TEST = False
|
3099
|
-
if Path("./betatest").exists():
|
3100
|
-
BETA_TEST = True
|
3101
|
-
|
3257
|
+
DEBUG_ENABLED = False
|
3102
3258
|
if Path("./debug").exists():
|
3103
|
-
|
3104
|
-
logger.debug("debugging on")
|
3105
|
-
else:
|
3106
|
-
logger.setLevel(logging.WARNING)
|
3107
|
-
# logger.warning("debugging off")
|
3259
|
+
DEBUG_ENABLED = True
|
3108
3260
|
|
3261
|
+
logger = logging.getLogger("__main__")
|
3262
|
+
|
3263
|
+
logging.basicConfig(
|
3264
|
+
level=logging.DEBUG if DEBUG_ENABLED else logging.CRITICAL,
|
3265
|
+
format="[%(asctime)s] %(levelname)s %(name)s - %(funcName)s Line %(lineno)d: %(message)s",
|
3266
|
+
handlers=[
|
3267
|
+
RotatingFileHandler(fsutils.LOG_FILE, maxBytes=10490000, backupCount=20),
|
3268
|
+
logging.StreamHandler(),
|
3269
|
+
],
|
3270
|
+
)
|
3271
|
+
logging.getLogger("PyQt5.uic.uiparser").setLevel("INFO")
|
3272
|
+
logging.getLogger("PyQt5.uic.properties").setLevel("INFO")
|
3273
|
+
os.environ["QT_QPA_PLATFORMTHEME"] = "gnome"
|
3109
3274
|
app = QtWidgets.QApplication(sys.argv)
|
3110
|
-
|
3111
|
-
|
3112
|
-
families
|
3113
|
-
logger.info(families)
|
3275
|
+
|
3276
|
+
families = load_fonts_from_dir(os.fspath(fsutils.APP_DATA_PATH))
|
3277
|
+
logger.info(f"font families {families}")
|
3114
3278
|
window = MainWindow()
|
3115
3279
|
height = window.pref.get("window_height", 300)
|
3116
3280
|
width = window.pref.get("window_width", 700)
|