diff --git a/main.py b/main.py
index 7135ca7..6f9bed3 100644
--- a/main.py
+++ b/main.py
@@ -8,6 +8,7 @@ from PyQt5.QtWidgets import (QMainWindow,
from PyQt5.QtGui import QPixmap
from PyQt5 import uic
from PyQt5.QtCore import QFileInfo, QSize
+import webbrowser
from audio_player import AudioPlayer
@@ -22,10 +23,40 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.show()
self.actionExit.triggered.connect(qApp.quit)
self.db_version = None
+ self.db = None
+ self.current_signal_name = ''
+ self.signal_names = []
+ self.category_labels = [self.cat_mil,
+ self.cat_rad,
+ self.cat_active,
+ self.cat_inactive,
+ self.cat_ham,
+ self.cat_comm,
+ self.cat_avi,
+ self.cat_mar,
+ self.cat_ana,
+ self.cat_dig,
+ self.cat_trunked,
+ self.cat_utility,
+ self.cat_sat,
+ self.cat_navi,
+ self.cat_interf,
+ self.cat_num_stat,
+ self.cat_time_sig,]
+
+ self.property_labels = [self.name_lab,
+ self.freq_lab,
+ self.band_lab,
+ self.mode_lab,
+ self.modul_lab,
+ self.loc_lab,
+ self.acf_lab,
+ self.description_text,]
+
+ self.url_button.clicked.connect(self.go_to_web_page_signal)
self.load_db()
self.display_signals()
self.search_bar.textChanged.connect(self.display_signals)
- self.result_list.itemSelectionChanged.connect(self.display_specs)
self.result_list.currentItemChanged.connect(self.display_specs)
self.audio_widget = AudioPlayer(self.play,
self.pause,
@@ -35,40 +66,53 @@ class MyApp(QMainWindow, Ui_MainWindow):
def load_db(self):
try:
- db = read_csv(os.path.join('Data', 'db.csv'),
- sep = '*',
- header = None,
- prefix = 'signal_')
+ self.db = read_csv(os.path.join('Data', 'db.csv'),
+ sep = '*',
+ header = None,
+ index_col = 0,
+ dtype = {'inf_freq': str,
+ 'sup_freq': str,
+ 'mode': str,
+ 'inf_band': str,
+ 'sup_band': str,
+ 'category_code': str,},
+ names = ["name",
+ "inf_freq",
+ "sup_freq",
+ "mode",
+ "inf_band",
+ "sup_band",
+ "location",
+ "url",
+ "description",
+ "modulation",
+ "category_code",
+ "acf",],
+ )
+ self.db.fillna("N/A", inplace = True)
except FileNotFoundError:
- self.signal_names = ''
self.search_bar.setDisabled(True)
box = QMessageBox(self)
- box.setStyleSheet("""
- color:#FFFFFF;
- """)
box.setWindowTitle("No database")
box.setText("No database available.\n"
"Go to Updates->Download database.")
box.show()
else:
- self.signal_names = db['signal_0']
+ self.signal_names = self.db.index
try:
with open(os.path.join('Data', 'verdb.ini'), 'r') as dbver:
self.db_version = int(dbver.read())
except (FileNotFoundError, ValueError):
box = QMessageBox(self)
- box.setStyleSheet("""
- color:#FFFFFF;
- """)
box.setWindowTitle("No database version")
box.setText("Unable to detect database version.\n"
"Possible data curruption.\n"
"Go to Updates->Force Download.")
box.show()
- self.setStatusTip(f"Database version: undefined.")
+ self.setStatusTip("Database version: undefined.")
else:
- self.setStatusTip(f"Database version: {self.db_version}.")
+ self.setStatusTip(f"Database version: {self.db_version}")
def display_signals(self):
@@ -81,10 +125,65 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.display_spectrogram()
item = self.result_list.currentItem()
if item:
- self.audio_widget.set_audio_player(item.text())
+ self.url_button.setEnabled(True)
+ self.url_button.setStyleSheet("color: #4c75ff;")
+ self.current_signal_name = item.text()
+ self.name_lab.setText(self.current_signal_name)
+ current_signal = self.db.loc[self.current_signal_name]
+ category_code = current_signal.loc["category_code"]
+ self.freq_lab.setText(self.format_numbers(
+ current_signal.loc["inf_freq"],
+ current_signal.loc["sup_freq"])
+ )
+ self.band_lab.setText(self.format_numbers(
+ current_signal.loc["inf_band"],
+ current_signal.loc["sup_band"])
+ )
+ self.mode_lab.setText(current_signal.loc["mode"])
+ self.modul_lab.setText(current_signal.loc["modulation"])
+ self.loc_lab.setText(current_signal.loc["location"])
+ self.acf_lab.setText(current_signal.loc["acf"])
+ self.description_text.setText(current_signal.loc["description"])
+ for cat, cat_lab in zip(category_code, self.category_labels):
+ if cat == '0':
+ cat_lab.setStyleSheet("color: #9f9f9f;")
+ elif cat == '1':
+ cat_lab.setStyleSheet("color: #39eaff;")
+ self.audio_widget.set_audio_player(self.current_signal_name)
else:
+ self.url_button.setEnabled(False)
+ self.url_button.setStyleSheet("color: #898989;")
+ self.current_signal_name = ''
+ for lab in self.property_labels:
+ lab.setText("N/A")
+ for lab in self.category_labels:
+ lab.setStyleSheet("""color: #9f9f9f;""")
self.audio_widget.set_audio_player()
+ @classmethod
+ def format_numbers(cls, lower, upper):
+ units = {1: 'Hz', 1000: 'kHz', 10**6: 'MHz', 10**9: 'GHz'}
+ lower_factor = cls.change_unit(lower)
+ upper_factor = cls.change_unit(upper)
+ if lower != upper:
+ lower = int(lower) / lower_factor
+ upper = int(upper) / upper_factor
+ return f"{lower} {units[lower_factor]} - {upper} {units[upper_factor]}"
+ else:
+ lower = int(lower) / lower_factor
+ return f"{lower} {units[lower_factor]}"
+
+ @staticmethod
+ def change_unit(num):
+ if len(num) < 4:
+ return 1
+ elif len(num) < 7:
+ return 1000
+ elif len(num) < 10:
+ return 10**6
+ else:
+ return 10**9
+
def display_spectrogram(self):
default_pic = os.path.join("icons_imgs", "image_not_found.png")
item = self.result_list.currentItem()
@@ -97,6 +196,11 @@ class MyApp(QMainWindow, Ui_MainWindow):
path_spectr = default_pic
self.spectrogram.setPixmap(QPixmap(path_spectr))
+ def go_to_web_page_signal(self):
+ if self.current_signal_name:
+ webbrowser.open(self.db.loc[self.current_signal_name].loc["url"])
+
+
if __name__ == '__main__':
my_app = QApplication(sys.argv)
diff --git a/main_window.ui b/main_window.ui
index d0364f2..920bc70 100644
--- a/main_window.ui
+++ b/main_window.ui
@@ -6,8 +6,8 @@
0
0
- 1000
- 800
+ 942
+ 568
@@ -24,6 +24,10 @@
background-color: #464646
}
+QLabel {
+ color: #ffffff;
+}
+
QPushButton {
color: #FFFFFF
}
@@ -108,6 +112,14 @@ QScrollBar::sub-page:horizontal{
border-radius: 5px;
/* border: 1px #343434;
background-color: #343434;*/
+}
+
+QTextEdit{
+ color: #ffffff;
+}
+
+QMessageBox {
+ color: #ffffff;
}
@@ -308,6 +320,701 @@ QTabBar::tab:!selected {
Main
+
+ -
+
+
-
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Categories
+
+
+ Qt::AlignBottom|Qt::AlignHCenter
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Military
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Radar
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Active
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Inactive
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ HAM
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Commercial
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Aviation
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Marine
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Analogue
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Digital
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Trunked
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Utility
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Sat
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Navigation
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Interfering
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Time Signal
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ color: #9f9f9f;
+
+
+ Number Stations
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Description
+
+
+
+ -
+
+
-
+
+
-
+
+
-
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Name
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Frequency
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Bandwidth
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Mode
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Modulation
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Location
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ ACF
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 10
+
+
+
+ N/A
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ N/A
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ N/A
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ N/A
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ N/A
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ N/A
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ N/A
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
-
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 12
+ 75
+ true
+ true
+
+
+
+ Go to the signal's wiki.
+
+
+ color: #898989;
+
+
+ Signal's wiki
+
+
+ true
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 10
+
+
+
+ border: 0px;
+/*border-radius: 8px;*/
+
+
+ Qt::ScrollBarAsNeeded
+
+
+ Qt::ScrollBarAsNeeded
+
+
+ true
+
+
+
+
@@ -572,6 +1279,9 @@ QSlider::handle:horizontal {
Signal waterfall
+
+
+
@@ -593,7 +1303,7 @@ QSlider::handle:horizontal {
0
0
- 1000
+ 942
21