diff --git a/.gitignore b/.gitignore index 4cca36c..bcc7033 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,7 @@ wav_converter.py to_do.txt csv_info.txt pyinstaller_cmd.txt -icons_imgs -TestData themes/.current_theme *.bat *.sh -splash.jpg \ No newline at end of file +.vscode/ diff --git a/artemis.py b/artemis.py index 759d21c..de1d2f7 100644 --- a/artemis.py +++ b/artemis.py @@ -1,6 +1,5 @@ from collections import namedtuple from functools import partial -from glob import glob import webbrowser import os import sys @@ -14,7 +13,6 @@ from PyQt5.QtWidgets import (QMainWindow, QListWidgetItem, QMessageBox, QSplashScreen, - QTreeView, QTreeWidgetItem,) from PyQt5.QtGui import QPixmap from PyQt5 import uic @@ -23,10 +21,9 @@ from PyQt5.QtCore import (QFileInfo, pyqtSlot,) from audio_player import AudioPlayer - -from double_text_button import DoubleTextButton +from space_weather_data import SpaceWeatherData from download_window import DownloadWindow - +from switchable_label import SwitchableLabelsIterable from constants import (Constants, Ftype, GfdType, @@ -35,7 +32,6 @@ from constants import (Constants, Messages, Signal,) from themes import Theme - from utilities import (checksum_ok, uncheck_and_emit, pop_up, @@ -43,11 +39,10 @@ from utilities import (checksum_ok, filters_ok, is_undef_freq, is_undef_band, - change_unit, format_numbers, resource_path,) -import icon_rc +# import icon_rc qt_creator_file = resource_path("artemis.ui") Ui_MainWindow, _ = uic.loadUiType(qt_creator_file) @@ -59,6 +54,7 @@ class Artemis(QMainWindow, Ui_MainWindow): self.setupUi(self) self.set_initial_size() self.download_window = DownloadWindow() + self.download_window.complete.connect(self.show_downloaded_signals) self.actionExit.triggered.connect(qApp.quit) self.action_update_database.triggered.connect(self.ask_if_download) self.action_check_db_ver.triggered.connect(self.check_db_ver) @@ -66,6 +62,66 @@ class Artemis(QMainWindow, Ui_MainWindow): self.current_signal_name = '' self.signal_names = [] self.total_signals = 0 + self.switchable_r_labels = SwitchableLabelsIterable(self.r0_now_lbl, + self.r1_now_lbl, + self.r2_now_lbl, + self.r3_now_lbl, + self.r4_now_lbl, + self.r5_now_lbl,) + + self.switchable_s_labels = SwitchableLabelsIterable(self.s0_now_lbl, + self.s1_now_lbl, + self.s2_now_lbl, + self.s3_now_lbl, + self.s4_now_lbl, + self.s5_now_lbl,) + + self.switchable_g_now_labels = SwitchableLabelsIterable(self.g0_now_lbl, + self.g1_now_lbl, + self.g2_now_lbl, + self.g3_now_lbl, + self.g4_now_lbl, + self.g5_now_lbl) + + self.switchable_g_today_labels = SwitchableLabelsIterable(self.g0_today_lbl, + self.g1_today_lbl, + self.g2_today_lbl, + self.g3_today_lbl, + self.g4_today_lbl, + self.g5_today_lbl) + + self.k_storm_labels = SwitchableLabelsIterable(self.k_ex_sev_storm_lbl, + self.k_very_sev_storm_lbl, + self.k_sev_storm_lbl, + self.k_maj_storm_lbl, + self.k_min_storm_lbl, + self.k_active_lbl, + self.k_unsettled_lbl, + self.k_quiet_lbl, + self.k_very_quiet_lbl, + self.k_inactive_lbl) + + self.a_storm_labels = SwitchableLabelsIterable(self.a_sev_storm_lbl, + self.a_maj_storm_lbl, + self.a_min_storm_lbl, + self.a_active_lbl, + self.a_unsettled_lbl, + self.a_quiet_lbl) + + self.forecast_labels = (self.forecast_lbl_0, + self.forecast_lbl_1, + self.forecast_lbl_2, + self.forecast_lbl_3, + self.forecast_lbl_4, + self.forecast_lbl_5, + self.forecast_lbl_6, + self.forecast_lbl_7, + self.forecast_lbl_8) + + for lab in self.forecast_labels: + lab.set_default_stylesheet() + + self.forecast_label_container.labels = self.forecast_labels self.theme = Theme(self) # Manage frequency filters. @@ -346,13 +402,10 @@ class Artemis(QMainWindow, Ui_MainWindow): # ########################################################################################## - # self.load_db() - # Left list widget and search bar. self.search_bar.textChanged.connect(self.display_signals) self.result_list.currentItemChanged.connect(self.display_specs) self.result_list.itemDoubleClicked.connect(lambda: self.main_tab.setCurrentWidget(self.signal_properties_tab)) - # self.display_signals() self.audio_widget = AudioPlayer(self.play, self.pause, self.stop, @@ -376,26 +429,186 @@ class Artemis(QMainWindow, Ui_MainWindow): BandLabel(self.ehf_left, self.ehf, self.ehf_right), ] + # Space weather + self.info_now_btn.clicked.connect(lambda : webbrowser.open(Constants.FORECAST_INFO)) + self.update_now_bar.clicked.connect(self.start_update_space_weather) + self.update_now_bar.set_idle() + self.space_weather_data = SpaceWeatherData() + self.space_weather_data.update_complete.connect(self.update_space_weather) + # Final operations. self.theme.initialize() self.load_db() self.display_signals() - self.show() + + @pyqtSlot() + def start_update_space_weather(self): + if not self.space_weather_data.is_updating: + self.update_now_bar.set_updating() + self.space_weather_data.update() + + @pyqtSlot(bool) + def update_space_weather(self, status_ok): + self.update_now_bar.set_idle() + if status_ok: + xray_long = float(self.space_weather_data.xray[-1][7]) + format_text = lambda letter, power : letter + f"{xray_long * 10**power:.1f}" + if xray_long < 1e-8 and xray_long != -1.00e+05: + self.peak_flux_lbl.setText(format_text("= 1e-8 and xray_long < 1e-7: + self.peak_flux_lbl.setText(format_text("A", 8)) + elif xray_long >= 1e-7 and xray_long < 1e-6: + self.peak_flux_lbl.setText(format_text("B", 7)) + elif xray_long >= 1e-6 and xray_long < 1e-5: + self.peak_flux_lbl.setText(format_text("C", 6)) + elif xray_long >= 1e-5 and xray_long < 1e-4: + self.peak_flux_lbl.setText(format_text("M", 5)) + elif xray_long >= 1e-4: + self.peak_flux_lbl.setText(format_text("X", 4)) + elif xray_long == -1.00e+05: + self.peak_flux_lbl.setText("No Data") + + if xray_long < 1e-5 and xray_long != -1.00e+05: + self.switchable_r_labels.switch_on(self.r0_now_lbl) + elif xray_long >= 1e-5 and xray_long < 5e-5: + self.switchable_r_labels.switch_on(self.r1_now_lbl) + elif xray_long >= 5e-5 and xray_long < 1e-4: + self.switchable_r_labels.switch_on(self.r2_now_lbl) + elif xray_long >= 1e-4 and xray_long < 1e-3: + self.switchable_r_labels.switch_on(self.r3_now_lbl) + elif xray_long >= 1e-3 and xray_long < 2e-3: + self.switchable_r_labels.switch_on(self.r4_now_lbl) + elif xray_long >= 2e-3: + self.switchable_r_labels.switch_on(self.r5_now_lbl) + elif xray_long == -1.00e+05: + self.switchable_r_labels.switch_off_all() + + pro10 = float(self.space_weather_data.prot_el[-1][8]) + if pro10 < 10 and pro10 != -1.00e+05: + self.switchable_s_labels.switch_on(self.s0_now_lbl) + elif pro10 >= 10 and pro10 < 100: + self.switchable_s_labels.switch_on(self.s1_now_lbl) + elif pro10 >= 100 and pro10 < 1000: + self.switchable_s_labels.switch_on(self.s2_now_lbl) + elif pro10 >= 1000 and pro10 < 10000: + self.switchable_s_labels.switch_on(self.s3_now_lbl) + elif pro10 >= 10000 and pro10 < 100000: + self.switchable_s_labels.switch_on(self.s4_now_lbl) + elif pro10 >= 100000: + self.switchable_s_labels.switch_on(self.s5_now_lbl) + elif pro10 == -1.00e+05: + self.switchable_s_labels.switch_off_all() + + k_index = int(self.space_weather_data.ak_index[8][11].replace('.', '')) + self.k_index_lbl.setText(str(k_index)) + a_index = int(self.space_weather_data.ak_index[7][7].replace('.', '')) + self.a_index_lbl.setText(str(a_index)) + + if k_index == 0: + self.switchable_g_now_labels.switch_on(self.g0_now_lbl) + self.k_storm_labels.switch_on(self.k_inactive_lbl) + elif k_index == 1: + self.switchable_g_now_labels.switch_on(self.g0_now_lbl) + self.k_storm_labels.switch_on(self.k_very_quiet_lbl) + elif k_index == 2: + self.switchable_g_now_labels.switch_on(self.g0_now_lbl) + self.k_storm_labels.switch_on(self.k_quiet_lbl) + elif k_index == 3: + self.switchable_g_now_labels.switch_on(self.g0_now_lbl) + self.k_storm_labels.switch_on(self.k_unsettled_lbl) + elif k_index == 4: + self.switchable_g_now_labels.switch_on(self.g0_now_lbl) + self.k_storm_labels.switch_on(self.k_active_lbl) + elif k_index == 5: + self.switchable_g_now_labels.switch_on(self.g1_now_lbl) + self.k_storm_labels.switch_on(self.k_min_storm_lbl) + elif k_index == 6: + self.switchable_g_now_labels.switch_on(self.g2_now_lbl) + self.k_storm_labels.switch_on(self.k_maj_storm_lbl) + elif k_index == 7: + self.switchable_g_now_labels.switch_on(self.g3_now_lbl) + self.k_storm_labels.switch_on(self.k_sev_storm_lbl) + elif k_index == 8: + self.switchable_g_now_labels.switch_on(self.g4_now_lbl) + self.k_storm_labels.switch_on(self.k_very_sev_storm_lbl) + elif k_index == 9: + self.switchable_g_now_labels.switch_on(self.g5_now_lbl) + self.k_storm_labels.switch_on(self.k_ex_sev_storm_lbl) + + if a_index >= 0 and a_index < 8: + self.a_storm_labels.switch_on(self.a_quiet_lbl) + elif a_index >= 8 and a_index < 16: + self.a_storm_labels.switch_on(self.a_unsettled_lbl) + elif a_index >= 16 and a_index < 30: + self.a_storm_labels.switch_on(self.a_active_lbl) + elif a_index >= 30 and a_index < 50: + self.a_storm_labels.switch_on(self.a_min_storm_lbl) + elif a_index >= 50 and a_index < 100: + self.a_storm_labels.switch_on(self.a_maj_storm_lbl) + elif a_index >= 100 and a_index < 400: + self.a_storm_labels.switch_on(self.a_sev_storm_lbl) + + index = self.space_weather_data.geo_storm[6].index("was") + 1 + k_index_24_hmax = int(self.space_weather_data.geo_storm[6][index]) + if k_index_24_hmax == 0: + self.switchable_g_today_labels.switch_on(self.g0_today_lbl) + self.expected_noise_lbl.setText(" S0 - S1 (<-120 dBm) ") + elif k_index_24_hmax == 1: + self.switchable_g_today_labels.switch_on(self.g0_today_lbl) + self.expected_noise_lbl.setText(" S0 - S1 (<-120 dBm) ") + elif k_index_24_hmax == 2: + self.switchable_g_today_labels.switch_on(self.g0_today_lbl) + self.expected_noise_lbl.setText(" S1 - S2 (-115 dBm) ") + elif k_index_24_hmax == 3: + self.switchable_g_today_labels.switch_on(self.g0_today_lbl) + self.expected_noise_lbl.setText(" S2 - S3 (-110 dBm) ") + elif k_index_24_hmax == 4: + self.switchable_g_today_labels.switch_on(self.g0_today_lbl) + self.expected_noise_lbl.setText(" S3 - S4 (-100 dBm) ") + elif k_index_24_hmax == 5: + self.switchable_g_today_labels.switch_on(self.g1_today_lbl) + self.expected_noise_lbl.setText(" S4 - S6 (-90 dBm) ") + elif k_index_24_hmax == 6: + self.switchable_g_today_labels.switch_on(self.g2_today_lbl) + self.expected_noise_lbl.setText(" S6 - S9 (-80 dBm) ") + elif k_index_24_hmax == 7: + self.switchable_g_today_labels.switch_on(self.g3_today_lbl) + self.expected_noise_lbl.setText(" S9 - S20 (>-60 dBm) ") + elif k_index_24_hmax == 8: + self.switchable_g_today_labels.switch_on(self.g4_today_lbl) + self.expected_noise_lbl.setText(" S20 - S30 (>-60 dBm) ") + elif k_index_24_hmax == 9: + self.switchable_g_today_labels.switch_on(self.g5_today_lbl) + self.expected_noise_lbl.setText(" S30+ (>>-60 dBm) ") + self.expected_noise_lbl.switch_on() + + val = int(self.space_weather_data.ak_index[7][2].replace('.', '')) + self.sfi_lbl.setText(f"{val}") + val = int([x[4] for x in self.space_weather_data.sgas if "SSN" in x][0]) + self.sn_lbl.setText(f"{val:d}") + + for label, pixmap in zip(self.forecast_labels, self.space_weather_data.images): + label.pixmap = pixmap + label.make_transparent() + label.apply_pixmap() + else: + pop_up(self, title = Messages.BAD_DOWNLOAD, + text = Messages.BAD_DOWNLOAD_MSG).show() + self.space_weather_data.remove_data() @pyqtSlot() def go_to_gfd(self, by): query = "/?q=" - if by == GfdType.FREQ: + if by is GfdType.FREQ: value_in_mhz = self.freq_gfd.value() * Constants.CONVERSION_FACTORS[self.unit_freq_gfd.currentText()] / Constants.CONVERSION_FACTORS["MHz"] query += str(value_in_mhz) - elif by == GfdType.LOC: + elif by is GfdType.LOC: query += self.gfd_line_edit.text() try: webbrowser.open(Constants.GFD_SITE + query.lower()) except: pass - @pyqtSlot(QListWidgetItem) def remove_if_unselected_modulation(self, item): if not item.isSelected(): @@ -417,7 +630,7 @@ class Artemis(QMainWindow, Ui_MainWindow): def show_matching_strings(self, list_elements, text): for index in range(list_elements.count()): item = list_elements.item(index) - if text.upper() in item.text() or item.isSelected(): + if text.lower() in item.text().lower() or item.isSelected(): item.setHidden(False) else: item.setHidden(True) @@ -441,10 +654,8 @@ class Artemis(QMainWindow, Ui_MainWindow): item.child(i).setSelected(True) def set_initial_size(self): - """ - Function to handle high resolution screens. The function sets bigger sizes - for all the relevant fixed-size widgets. - """ + """Function to handle high resolution screens. The function sets bigger sizes + for all the relevant fixed-size widgets.""" d = QDesktopWidget().availableGeometry() w = d.width() h = d.height() @@ -492,7 +703,6 @@ class Artemis(QMainWindow, Ui_MainWindow): @pyqtSlot() def download_db(self): if not self.download_window.isVisible(): - self.download_window.download_thread.finished.connect(self.show_downloaded_signals) self.download_window.download_thread.start() self.download_window.show() @@ -536,6 +746,8 @@ class Artemis(QMainWindow, Ui_MainWindow): text = Messages.NO_DB_AVAIL, informative_text = Messages.DOWNLOAD_NOW_QUESTION, is_question = True).exec() + if answer == QMessageBox.Yes: + self.download_db() else: try: is_checksum_ok = checksum_ok(db, ChecksumWhat.DB) @@ -546,7 +758,6 @@ class Artemis(QMainWindow, Ui_MainWindow): if is_checksum_ok: pop_up(self, title = Messages.DB_UP_TO_DATE, text = Messages.DB_UP_TO_DATE_MSG).show() - else: answer = pop_up(self, title = Messages.DB_NEW_VER, text = Messages.DB_NEW_VER_MSG, @@ -557,10 +768,9 @@ class Artemis(QMainWindow, Ui_MainWindow): @pyqtSlot() def show_downloaded_signals(self): - if self.download_window.everything_ok: - self.search_bar.setEnabled(True) - self.load_db() - self.display_signals() + self.search_bar.setEnabled(True) + self.load_db() + self.display_signals() def load_db(self): names = Database.NAMES @@ -585,7 +795,9 @@ class Artemis(QMainWindow, Ui_MainWindow): self.db.fillna(Constants.UNKNOWN, inplace = True) self.db[Signal.WIKI_CLICKED] = False self.update_status_tip(self.total_signals) + self.result_list.clear() self.result_list.addItems(self.signal_names) + self.result_list.setCurrentItem(None) @pyqtSlot() def set_min_value_upper_limit(self, lower_combo_box, @@ -599,7 +811,6 @@ class Artemis(QMainWindow, Ui_MainWindow): lower_units = lower_combo_box.currentText() upper_units = upper_combo_box.currentText() lower_value = lower_spin_box.value() - upper_value = upper_spin_box.value() inf_limit = (lower_value * Constants.CONVERSION_FACTORS[lower_units]) \ // Constants.CONVERSION_FACTORS[upper_units] counter = 0 @@ -703,7 +914,7 @@ class Artemis(QMainWindow, Ui_MainWindow): else: self.result_list.item(index).setHidden(True) # Remove selected item. - self.result_list.selectionModel().clear() + self.result_list.setCurrentItem(None) self.update_status_tip(available_signals) def update_status_tip(self, available_signals): @@ -756,8 +967,15 @@ class Artemis(QMainWindow, Ui_MainWindow): @pyqtSlot() def reset_mode_filters(self): uncheck_and_emit(self.apply_remove_mode_filter_btn) + parents = Constants.MODES.keys() + selected_children = [] for item in self.mode_tree_widget.selectedItems(): - item.setSelected(False) + if item.text(0) in parents: + item.setSelected(False) + else: + selected_children.append(item) + for children in selected_children: + children.setSelected(False) if self.include_unknown_modes_btn.isChecked(): self.include_unknown_modes_btn.setChecked(False) @@ -877,7 +1095,6 @@ class Artemis(QMainWindow, Ui_MainWindow): selected_items = [item for item in self.mode_tree_widget.selectedItems()] selected_items_text = [i.text(0) for i in selected_items] parents = [item for item in selected_items_text if item in Constants.MODES.keys()] - children = [item for item in selected_items_text if item not in parents] ok = [] for item in selected_items: if item.text(0) in parents: @@ -1042,11 +1259,11 @@ class Artemis(QMainWindow, Ui_MainWindow): if __name__ == '__main__': my_app = QApplication(sys.argv) - img = QPixmap(":/icons/Artemis3.500px.png") - # img = img.scaled(600, 600, aspectRatioMode = Qt.KeepAspectRatio) - splash = QSplashScreen(img) - splash.show() - sleep(2) - w = Artemis() - splash.finish(w) + # img = QPixmap(":/icons/Artemis3.500px.png") + # splash = QSplashScreen(img) + # splash.show() + # sleep(2) + artemis = Artemis() + artemis.show() + # splash.finish(w) sys.exit(my_app.exec_()) diff --git a/artemis.ui b/artemis.ui index 8a5ed46..33b2a73 100644 --- a/artemis.ui +++ b/artemis.ui @@ -6,8 +6,8 @@ 0 0 - 1206 - 634 + 1387 + 761 @@ -199,8 +199,46 @@ Main - - + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 90 + 20 + + + + + + + + + 11 + + + + border: 0px; +/*border-radius: 8px;*/ + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + + @@ -233,297 +271,391 @@ p, li { white-space: pre-wrap; } - - - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Mode - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Frequency - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Modulation - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Location - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Bandwidth - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - ACF - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Description + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 90 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Mode + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Frequency + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Modulation + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Location + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Bandwidth + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + ACF + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + 0 + 0 + + + + + + + false + + + + 0 + 0 + + + + + 12 + 75 + true + true + + + + <html><head/><body><p><span style=" color:#000000;">Go to the signal's wiki.</span></p></body></html> + + + + + + Signal's wiki + + + true + + + + + + + - + @@ -1032,99 +1164,25 @@ p, li { white-space: pre-wrap; } - - - - - 0 - 0 - - - - - - - false - - - - 0 - 0 - - - - - 12 - 75 - true - true - - - - <html><head/><body><p><span style=" color:#000000;">Go to the signal's wiki.</span></p></body></html> - - - - - - Signal's wiki - - - true - - - - - - - - - - - 0 - 0 - + + + + Qt::Vertical - - - 12 - 75 - true - + + QSizePolicy::MinimumExpanding - - Description + + + 20 + 20 + - - Qt::AlignCenter - - + - - - - - 11 - - - - border: 0px; -/*border-radius: 8px;*/ - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - true - - - - + <html><head/><body><p><span style=" color:#000000;">Frequency bands</span></p></body></html> @@ -3519,20 +3577,20 @@ Inactive Mode - - + + Qt::Horizontal - 171 + 170 20 - + @@ -3569,50 +3627,6 @@ Inactive - - - - Qt::Horizontal - - - - 170 - 20 - - - - - - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - @@ -3630,6 +3644,66 @@ Inactive + + + + + 12 + 75 + true + + + + Apply + + + true + + + + + + + + 12 + 75 + true + + + + Reset + + + + + + + Qt::Horizontal + + + + 171 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 20 + + + + @@ -4601,6 +4675,2182 @@ www.qrg.globaltuners.com + + + Rx/Tx Conditions + + + + + + + Now + + + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + 13 + 75 + true + true + + + + X-Rays + + + + + + + + + + 0 + 0 + + + + + 11 + + + + Radio Blackout + + + + + + + + 0 + 0 + + + + + 2 + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + R0 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + R1 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + R2 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + R3 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + R4 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + R5 + + + Qt::AlignCenter + + + + + + + + + + + + + 0 + 0 + + + + + 13 + 75 + true + true + + + + Protons-Electrons Flux + + + + + + + + + + 0 + 0 + + + + + 11 + + + + Solar Radiation Storm + + + + + + + + 0 + 0 + + + + + 2 + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + S0 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + S1 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + S2 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + S3 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + S4 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + S5 + + + Qt::AlignCenter + + + + + + + + + + + + + 0 + 0 + + + + + 13 + 75 + true + true + + + + Solar Activity + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + K-Index: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + A-Index: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + + + 0 + 0 + + + + + 1 + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + EXTREMELY SEVERE +STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + VERY SEVERE STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + SEVERE STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + MAJOR STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + MINOR STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + ACTIVE + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + UNSETTLED + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + QUIET + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + VERY QUIET + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + INACTIVE + + + Qt::AlignCenter + + + + + + + + + + + 0 + 0 + + + + + 1 + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + SEVERE STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + MAJOR STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + MINOR STORM + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + ACTIVE + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + UNSETTLED + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + + + + QUIET + + + Qt::AlignCenter + + + + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + SFI: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + SN: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + + + + + + + + + + + + 0 + 0 + + + + + 11 + + + + Geomagnetic Storm (now) + + + + + + + + 0 + 0 + + + + + 11 + + + + Geomagnetic Storm (MAX 24 hrs) + + + + + + + + + + + + 0 + 0 + + + + + 2 + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G0 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G1 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G2 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G3 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G4 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G5 + + + Qt::AlignCenter + + + + + + + + + + + 0 + 0 + + + + + 2 + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G0 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G1 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G2 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G3 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G4 + + + Qt::AlignCenter + + + + + + + + 10 + 75 + true + + + + color:#ffffff; +background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #283048 ,stop: 1 #859398); + + + G5 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 11 + + + + Peak Flux Class + + + + + + + + 0 + 0 + + + + + 12 + + + + N/A + + + Qt::AlignCenter + + + + + + + + + + + + + 0 + 0 + + + + + + + + 13 + 75 + true + true + + + + Propagation Data + + + + + + + + + + 0 + 0 + + + + + 9 + + + 0 + + + + + + 0 + 0 + + + + + 13 + false + + + + E.M.E→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + 50 MHz in EU→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + VHF Aurora→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + Hystorical Index→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + 144 MHz in EU→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + M.U.F.→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + Meteor Scatter→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + 144 MHz in NA→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + 13 + false + + + + 70 MHz in EU→ + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 15 + + + + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Qt::NoFocus + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 0 + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + + + + NO DATA + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 12 + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + + + + + + 0 + 0 + + + + + 13 + 75 + true + true + + + + Expected HF Noise + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 5 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + N/A + + + Qt::AlignCenter + + + 0 + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + + + + + + + + 0 + 0 + + + + Info + + + + + + + + 0 + 0 + + + + + 8 + 75 + true + + + + + + + 1 + + + -1 + + + Qt::AlignCenter + + + true + + + %p% + + + + + + + + + + + + + Tab 2 + + + + + + @@ -4858,7 +7108,7 @@ QSlider::handle:horizontal { 0 0 - 1206 + 1387 21 @@ -4917,6 +7167,27 @@ QSlider::handle:horizontal { QPushButton
double_text_button.h
+ + SwitchableLabel + QLabel +
switchable_label.h
+
+ + ClickableProgressBar + QProgressBar +
clickable_progress_bar.h
+
+ + FixedAspectRatioWidget + QWidget +
fixed_aspect_ratio_widget.h
+ 1 +
+ + FixedAspectRatioLabel + QLabel +
fixed_aspect_ratio_label.h
+
diff --git a/clickable_progress_bar.py b/clickable_progress_bar.py new file mode 100644 index 0000000..0cbf2fc --- /dev/null +++ b/clickable_progress_bar.py @@ -0,0 +1,31 @@ +from PyQt5.QtWidgets import QProgressBar +from PyQt5.QtCore import Qt, pyqtSignal +from constants import Constants + +class ClickableProgressBar(QProgressBar): + + clicked = pyqtSignal() + + def __init__(self, parent = None): + self.__text = '' + super().__init__(parent) + + def __set_text(self, text): + self.__text = text + + def text(self): + return self.__text + + def set_idle(self): + self.__set_text(Constants.CLICK_TO_UPDATE_STR) + self.setMaximum(self.minimum() + 1) + + def set_updating(self): + self.__set_text(Constants.UPDATING_STR) + self.setMaximum(self.minimum()) + + def mousePressEvent(self, event): + if event.button() == Qt.LeftButton: + self.clicked.emit() + else: + super().mousePressEvent(event) diff --git a/constants.py b/constants.py index 16f8617..559dc47 100644 --- a/constants.py +++ b/constants.py @@ -67,50 +67,70 @@ class Database(object): Signal.CATEGORY_CODE,) class Constants(object): - ACF_DOCS = "https://aresvalley.com/documentation/" - SEARCH_LABEL_IMG = "search_icon.png" - VOLUME_LABEL_IMG = "volume.png" - DATA_FOLDER = "Data" - SPECTRA_FOLDER = "Spectra" - SPECTRA_EXT = ".png" - AUDIO_FOLDER = "Audio" - ACTIVE = "active" - INACTIVE = "inactive" - NOT_AVAILABLE = "spectrumnotavailable.png" - NOT_SELECTED = "nosignalselected.png" - __Band = namedtuple("Band", ["lower", "upper"]) - __ELF = __Band(0, 30) # Formally it is (3, 30) Hz. - __SLF = __Band(30, 300) - __ULF = __Band(300, 3000) - __VLF = __Band(3000, 30000) - __LF = __Band(30 * 10**3, 300 * 10**3) - __MF = __Band(300 * 10 ** 3, 3000 * 10**3) - __HF = __Band(3 * 10**6, 30 * 10**6) - __VHF = __Band(30 * 10**6, 300 * 10**6) - __UHF = __Band(300 * 10**6, 3000 * 10**6) - __SHF = __Band(3 * 10**9, 30 * 10**9) - __EHF = __Band(30 * 10**9, 300 * 10**9) - BANDS = (__ELF, __SLF, __ULF, __VLF, __LF, __MF, __HF, __VHF, __UHF, __SHF, __EHF) - MAX_DIGITS = 3 - RANGE_SEPARATOR = ' ÷ ' - GFD_SITE = "http://qrg.globaltuners.com/" - CONVERSION_FACTORS = {"Hz" : 1, - "kHz": 1000, - "MHz": 1000000, - "GHz": 1000000000} - MODES = {"FM": ("NFM", "WFM"), - "AM": (), - "CW": (), - "SK": ("FSK", "PSK", "MSK"), - "SB": ("LSB", "USB", "DSB"), - "Chirp Spread Spectrum": (), - "FHSS-TDM": (), - "RAW": (), - "SC-FDMA": (),} - APPLY = "Apply" - REMOVE = "Remove" - UNKNOWN = "N/A" - MODULATIONS = ("8VSB", + CLICK_TO_UPDATE_STR = "Click to update" + UPDATING_STR = "Updating..." + ACF_DOCS = "https://aresvalley.com/documentation/" + FORECAST_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt" + FORECAST_PROT = "https://services.swpc.noaa.gov/text/goes-particle-flux-primary.txt" + FORECAST_AK_IND = "https://services.swpc.noaa.gov/text/wwv.txt" + FORECAST_SGAS = "https://services.swpc.noaa.gov/text/sgas.txt" + FORECAST_G = "https://services.swpc.noaa.gov/text/3-day-forecast.txt" + FORECAST_INFO = "https://www.swpc.noaa.gov/sites/default/files/images/NOAAscales.pdf" + FORECAST_IMG_0 = "http://www.mmmonvhf.de/eme/eme.png" + FORECAST_IMG_1 = "http://www.mmmonvhf.de/ms/ms.png" + FORECAST_IMG_2 = "http://www.mmmonvhf.de/es/es.png" + FORECAST_IMG_3 = "http://www.mmmonvhf.de/solar/solar.png" + FORECAST_IMG_4 = "http://amunters.home.xs4all.nl/eskipstatusNA.gif" + FORECAST_IMG_5 = "http://amunters.home.xs4all.nl/aurorastatus.gif" + FORECAST_IMG_6 = "http://amunters.home.xs4all.nl/eskipstatus.gif" + FORECAST_IMG_7 = "http://amunters.home.xs4all.nl/eskip50status.gif" + FORECAST_IMG_8 = "http://amunters.home.xs4all.nl/eskip70status.gif" + SEARCH_LABEL_IMG = "search_icon.png" + VOLUME_LABEL_IMG = "volume.png" + DATA_FOLDER = "Data" + SPECTRA_FOLDER = "Spectra" + SPECTRA_EXT = ".png" + AUDIO_FOLDER = "Audio" + ACTIVE = "active" + INACTIVE = "inactive" + LABEL_ON_COLOR = "on" + LABEL_OFF_COLOR = "off" + TEXT_COLOR = "text" + NOT_AVAILABLE = "spectrumnotavailable.png" + NOT_SELECTED = "nosignalselected.png" + __Band = namedtuple("Band", ["lower", "upper"]) + __ELF = __Band(0, 30) # Formally it is (3, 30) Hz. + __SLF = __Band(30, 300) + __ULF = __Band(300, 3000) + __VLF = __Band(3000, 30000) + __LF = __Band(30 * 10**3, 300 * 10**3) + __MF = __Band(300 * 10 ** 3, 3000 * 10**3) + __HF = __Band(3 * 10**6, 30 * 10**6) + __VHF = __Band(30 * 10**6, 300 * 10**6) + __UHF = __Band(300 * 10**6, 3000 * 10**6) + __SHF = __Band(3 * 10**9, 30 * 10**9) + __EHF = __Band(30 * 10**9, 300 * 10**9) + BANDS = (__ELF, __SLF, __ULF, __VLF, __LF, __MF, __HF, __VHF, __UHF, __SHF, __EHF) + MAX_DIGITS = 3 + RANGE_SEPARATOR = ' ÷ ' + GFD_SITE = "http://qrg.globaltuners.com/" + CONVERSION_FACTORS = {"Hz" : 1, + "kHz": 1000, + "MHz": 1000000, + "GHz": 1000000000} + MODES = {"FM": ("NFM", "WFM"), + "AM": (), + "CW": (), + "SK": ("FSK", "PSK", "MSK"), + "SB": ("LSB", "USB", "DSB"), + "Chirp Spread Spectrum": (), + "FHSS-TDM": (), + "RAW": (), + "SC-FDMA": (),} + APPLY = "Apply" + REMOVE = "Remove" + UNKNOWN = "N/A" + MODULATIONS = ("8VSB", "AFSK", "AM", "BFSK", @@ -135,34 +155,34 @@ class Constants(object): "PSK", "QAM", "TDMA",) - LOCATIONS = (UNKNOWN, - "Australia", - "Canada", - "Central Europe", - "China", - "Cyprus", - "Eastern Europe", - "Europe", - "Europe, japan and Asia", - "Exmouth, Australia", - "Finland", - "France", - "Germany", - "Home Base Mobile , AL", - "Hungary", - "Iran", - "Israel", - "Japan", - "LaMour, North Dakota", - "Lualualei, Hawaii", - "North America", - "North Korea", - "Poland", - "Romania", - "Ruda, Sweden", - "UK", - "United Kingdom", - "United States", - "Varberg, Sweden", - "World Wide", - "Worldwide",) + LOCATIONS = (UNKNOWN, + "Australia", + "Canada", + "Central Europe", + "China", + "Cyprus", + "Eastern Europe", + "Europe", + "Europe, japan and Asia", + "Exmouth, Australia", + "Finland", + "France", + "Germany", + "Home Base Mobile , AL", + "Hungary", + "Iran", + "Israel", + "Japan", + "LaMour, North Dakota", + "Lualualei, Hawaii", + "North America", + "North Korea", + "Poland", + "Romania", + "Ruda, Sweden", + "UK", + "United Kingdom", + "United States", + "Varberg, Sweden", + "World Wide", + "Worldwide",) diff --git a/download_window.py b/download_window.py index 8b0df8e..6957f63 100644 --- a/download_window.py +++ b/download_window.py @@ -1,5 +1,5 @@ from PyQt5 import uic -from PyQt5.QtCore import Qt, pyqtSlot +from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal from PyQt5.QtWidgets import QWidget from threads import DownloadThread, ThreadStatus from utilities import pop_up, resource_path @@ -8,6 +8,9 @@ from constants import Messages Ui_Download_window, _ = uic.loadUiType(resource_path("download_db_window.ui")) class DownloadWindow(QWidget, Ui_Download_window): + + complete = pyqtSignal() + def __init__(self): super().__init__() self.setupUi(self) @@ -18,7 +21,6 @@ class DownloadWindow(QWidget, Ui_Download_window): Qt.WindowCloseButtonHint #| # Qt.WindowStaysOnTopHint ) - self.everything_ok = True self.no_internet_msg = pop_up(self, title = Messages.NO_CONNECTION, text = Messages.NO_CONNECTION_MSG, @@ -30,17 +32,8 @@ class DownloadWindow(QWidget, Ui_Download_window): self.download_thread = DownloadThread() self.download_thread.finished.connect(self.wait_close) - self.cancel_btn.clicked.connect(self.terminate_process) - def show_no_connection_warning(self): - self.no_internet_msg.show() - self.everything_ok = False - - def show_bad_download_warning(self): - self.bad_db_download_msg.show() - self.everything_ok = False - @pyqtSlot() def terminate_process(self): if self.download_thread.isRunning(): @@ -50,12 +43,13 @@ class DownloadWindow(QWidget, Ui_Download_window): @pyqtSlot() def wait_close(self): - if self.download_thread.status == ThreadStatus.OK: + if self.download_thread.status is ThreadStatus.OK: + self.complete.emit() self.close() - elif self.download_thread.status == ThreadStatus.NO_CONNECTION_ERR: - self.show_no_connection_warning() - elif self.download_thread.status == ThreadStatus.BAD_DOWNLOAD_ERR: - self.show_bad_download_warning() + elif self.download_thread.status is ThreadStatus.NO_CONNECTION_ERR: + self.no_internet_msg.show() + elif self.download_thread.status is ThreadStatus.BAD_DOWNLOAD_ERR: + self.bad_db_download_msg.show() else: self.close() diff --git a/fixed_aspect_ratio_label.py b/fixed_aspect_ratio_label.py new file mode 100644 index 0000000..27c00e8 --- /dev/null +++ b/fixed_aspect_ratio_label.py @@ -0,0 +1,27 @@ +from PyQt5.QtWidgets import QLabel +from PyQt5.QtCore import Qt + +class FixedAspectRatioLabel(QLabel): + def __init__(self, parent = None): + super().__init__(parent) + self.pixmap = None + + def set_default_stylesheet(self): + self.setStyleSheet(""" + color: #ffffff; + background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 #304352 ,stop: 1 #d7d2cc); + """) + + def make_transparent(self): + self.setText('') + self.setStyleSheet("background-color: transparent;") + + def apply_pixmap(self): + if self.pixmap: + self.setPixmap( + self.pixmap.scaled( + self.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) + + def rescale(self, size): + self.resize(size) + self.apply_pixmap() diff --git a/fixed_aspect_ratio_widget.py b/fixed_aspect_ratio_widget.py new file mode 100644 index 0000000..71e78f9 --- /dev/null +++ b/fixed_aspect_ratio_widget.py @@ -0,0 +1,20 @@ +from PyQt5.QtWidgets import QWidget +from PyQt5.QtCore import QSize + +class FixedAspectRatioWidget(QWidget): + space = 10 + def __init__(self, parent = None): + super().__init__(parent) + self.labels = [] + + def resizeEvent(self, event): + h, w = self.height(), self.width() + h_lbl = h / 9 - self.space + w_lbl = 5 * h_lbl + + if w_lbl > w: + w_lbl = w + h_lbl = h / 9 - self.space + + for label in self.labels: + label.rescale(QSize(w_lbl, h_lbl)) diff --git a/icons_imgs/search_icon.png b/icons_imgs/search_icon.png deleted file mode 100644 index cc72a1e..0000000 Binary files a/icons_imgs/search_icon.png and /dev/null differ diff --git a/icons_imgs/volume.png b/icons_imgs/volume.png deleted file mode 100644 index 5cc5645..0000000 Binary files a/icons_imgs/volume.png and /dev/null differ diff --git a/main_window.ui b/main_window.ui deleted file mode 100644 index 21be4d1..0000000 --- a/main_window.ui +++ /dev/null @@ -1,4916 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1206 - 634 - - - - - 0 - 0 - - - - ARTEMIS3 - - - - :/icons/Artemis3.ico:/icons/Artemis3.ico - - - - - - - - - - Qt::Horizontal - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 2 - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 20 - 20 - - - - - 20 - 20 - - - - - - - themes/1-default/icons/search_icon.png - - - true - - - - - - - - 0 - 0 - - - - - 9 - 50 - false - - - - - - - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - 16 - - - false - - - - - - - - true - - - - 1 - 0 - - - - - 200 - 400 - - - - Qt::LeftToRight - - - - - - QTabWidget::North - - - QTabWidget::Rounded - - - 0 - - - true - - - - - 0 - 0 - - - - - 0 - 0 - - - - Main - - - - - - - 0 - 0 - - - - - 20 - 75 - true - - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:20pt; font-weight:600; font-style:normal;"> -<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">No Signal</p></body></html> - - - - - - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Mode - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Frequency - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Modulation - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Location - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 12 - - - - N/A - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Bandwidth - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - ACF - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - 0 - 0 - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Categories - - - Qt::AlignBottom|Qt::AlignHCenter - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Military - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Radar - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Active - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Inactive - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - HAM - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Commercial - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Aviation - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Marine - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Analogue - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Digital - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Trunked - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Utility - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Sat - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Navigation - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Interfering - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Time Signal - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - color: #9f9f9f; - - - Number Stations - - - Qt::AlignCenter - - - - - - - - - - - 0 - 0 - - - - - - - false - - - - 0 - 0 - - - - - 12 - 75 - true - true - - - - <html><head/><body><p><span style=" color:#000000;">Go to the signal's wiki.</span></p></body></html> - - - - - - Signal's wiki - - - true - - - - - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Description - - - Qt::AlignCenter - - - - - - - - 11 - - - - border: 0px; -/*border-radius: 8px;*/ - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - true - - - - - - - <html><head/><body><p><span style=" color:#000000;">Frequency bands</span></p></body></html> - - - color: #9f9f9f; - - - - - - - - - 12 - 75 - true - - - - color: #9f9f9f; - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - ELF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - color: #9f9f9f; - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - color: #9f9f9f; - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - color: #9f9f9f; - - - SLF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - ULF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - VLF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - LF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - MF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - color: #9f9f9f; - - - HF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - VHF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - UHF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - SHF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - color: #9f9f9f; - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - 12 - 75 - true - - - - █ - - - Qt::AlignCenter - - - - - - - - 9 - 75 - true - - - - EHF - - - Qt::AlignCenter - - - - - - - - 12 - 75 - true - - - - color: #9f9f9f; - - - █ - - - Qt::AlignCenter - - - - - - - - - - - - - Filters - - - - - - - - - 0 - - - true - - - - Frequency - - - - - - - 0 - 0 - - - - - - - - - - true - - - - 0 - 0 - - - - - 12 - 75 - true - - - - ELF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - SLF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - ULF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - VLF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - LF - - - true - - - - - - - true - - - - 0 - 0 - - - - - 12 - 75 - true - - - - MF - - - true - - - - - - - true - - - - 0 - 0 - - - - - 12 - 75 - true - - - - HF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - VHF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - UHF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - SHF - - - true - - - - - - - true - - - - 12 - 75 - true - - - - EHF - - - true - - - false - - - - - - - - - - Qt::Horizontal - - - - 24 - 20 - - - - - - - - - 0 - 0 - - - - - - - - - - - 12 - 75 - true - - - - Lower frequency - - - false - - - - - - - false - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 100000000 - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 16777215 - 16777215 - - - - - 12 - 75 - true - - - - - - - MHz - - - 4 - - - false - - - 0 - - - - MHz - - - - - Hz - - - - - kHz - - - - - GHz - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 0 - - - - - - - - 12 - 75 - true - - - - Upper frequency - - - false - - - - - - - false - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 100000000 - - - 1 - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 16777215 - 16777215 - - - - - 12 - 75 - true - - - - - - - MHz - - - - MHz - - - - - Hz - - - - - kHz - - - - - GHz - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 0 - - - - - - - false - - - - 0 - 0 - - - - - 12 - 75 - false - true - false - - - - color: #9f9f9f; - - - Selected range: - -Inactive - - - Qt::AlignCenter - - - - - - - - - - Qt::Horizontal - - - - 24 - 20 - - - - - - - - - 12 - 75 - true - - - - Include undefined frequencies - - - true - - - - - - - true - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - - - - - - Bandwidth - - - - - - Qt::Horizontal - - - - 44 - 20 - - - - - - - - - 0 - 0 - - - - - - - - - - false - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 100000000 - - - 5000 - - - - - - - false - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 100000000 - - - 5000 - - - - - - - - 12 - 75 - true - - - - Upper band - - - false - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 0 - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 16777215 - 16777215 - - - - - 12 - 75 - true - - - - - - - MHz - - - 4 - - - false - - - 0 - - - - MHz - - - - - Hz - - - - - kHz - - - - - GHz - - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 0 - - - - - - - false - - - - 0 - 0 - - - - - 60 - 0 - - - - - 16777215 - 16777215 - - - - - 12 - 75 - true - - - - - - - MHz - - - - MHz - - - - - Hz - - - - - kHz - - - - - GHz - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 12 - 75 - true - - - - Lower band - - - false - - - - - - - false - - - - 0 - 0 - - - - - 12 - 75 - false - true - false - - - - - - - Selected range: - -Inactive - - - Qt::AlignCenter - - - - - - - - - - Qt::Horizontal - - - - 44 - 20 - - - - - - - - true - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - - - - - - 12 - 75 - true - - - - Include undefined bandwidths - - - true - - - - - - - - Category - - - - - - Qt::Horizontal - - - - 102 - 20 - - - - - - - - - 50 - - - - - - 12 - 75 - true - - - - <html><head/><body><p>Keep all the signals which belong to <span style=" font-style:italic;">at least</span> one of the selected categories.</p></body></html> - - - - - - At least one selected - - - true - - - - - - - - 12 - 75 - true - - - - <html><head/><body><p>Keep all the signals which belong to <span style=" font-style:italic;">all </span>the selected categories.</p></body></html> - - - All selected - - - false - - - - - - - - - - Qt::Horizontal - - - - 102 - 20 - - - - - - - - - 0 - 0 - - - - - - - - 12 - 75 - true - - - - Number Stations - - - true - - - - - - - - 12 - 75 - true - - - - Time Signal - - - true - - - - - - - - 12 - 75 - true - - - - Interfering - - - true - - - - - - - - 12 - 75 - true - - - - Satellite - - - true - - - - - - - - 12 - 75 - true - - - - Navigation - - - true - - - - - - - - 12 - 75 - true - - - - Utility - - - true - - - - - - - - 12 - 75 - true - - - - Digital - - - true - - - - - - - - 12 - 75 - true - - - - Marine - - - true - - - - - - - - 12 - 75 - true - - - - Commercial - - - true - - - - - - - - 12 - 75 - true - - - - Inactive - - - true - - - - - - - - 12 - 75 - true - - - - Radar - - - true - - - - - - - - 12 - 75 - true - - - - Military - - - true - - - - - - - - 12 - 75 - true - - - - Active - - - true - - - - - - - - 12 - 75 - true - - - - HAM - - - true - - - - - - - - 12 - 75 - true - - - - Aviation - - - true - - - - - - - - 12 - 75 - true - - - - Analogue - - - true - - - - - - - - 12 - 75 - true - - - - Trunked - - - true - - - - - - - - - - true - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - - - - - - Mode - - - - - - Qt::Horizontal - - - - 171 - 20 - - - - - - - - - 12 - 75 - true - - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectItems - - - true - - - true - - - 1 - - - - 1 - - - - - - - - Qt::Horizontal - - - - 170 - 20 - - - - - - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - - - - - - 12 - 75 - true - - - - Include unknown modulations - - - true - - - - - - - - Modulation - - - - - - Qt::Horizontal - - - - 162 - 20 - - - - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - 20 - 20 - - - - - 20 - 20 - - - - - - - icons_imgs/search_icon.png - - - true - - - Qt::AlignCenter - - - - - - - - 12 - 50 - false - - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::MultiSelection - - - - - - - - - - Qt::Horizontal - - - - 161 - 20 - - - - - - - - true - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - - - - - - Location - - - - - - Qt::Horizontal - - - - 162 - 20 - - - - - - - - - - - - - - - 0 - 0 - - - - - 20 - 20 - - - - - - - icons_imgs/search_icon.png - - - true - - - - - - - - 12 - - - - QAbstractItemView::MultiSelection - - - - - - - - - - Qt::Horizontal - - - - 161 - 20 - - - - - - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - false - - - - - - - - ACF - - - - - - Qt::Horizontal - - - - 52 - 22 - - - - - - - - - - - - - - 12 - 75 - true - - - - AC interval - - - - - - - true - - - - 0 - 0 - - - - - 80 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 10000 - - - 50 - - - - - - - - 12 - 75 - true - - - - ms - - - - - - - Qt::Horizontal - - - - 49 - 20 - - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Confidence % - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - true - - - - 0 - 0 - - - - - 60 - 0 - - - - - 50 - 16777215 - - - - - 12 - - - - - - - false - - - Qt::AlignCenter - - - QAbstractSpinBox::UpDownArrows - - - - - - 100 - - - 0 - - - - - - - - - false - - - - 0 - 0 - - - - - 12 - 75 - false - true - false - - - - - - - Selected range: - -Inactive - - - Qt::AlignCenter - - - - - - - - - - Qt::Horizontal - - - - 51 - 20 - - - - - - - - - 12 - 75 - true - - - - Include undefined ACFs - - - true - - - - - - - - 12 - 75 - true - - - - Apply - - - true - - - - - - - - 12 - 75 - true - - - - Reset - - - false - - - - - - - - 12 - 75 - true - - - - Info - - - - - - - - - - - true - - - - 15 - 75 - true - - - - - - - Reset all filters - - - - - - - - GFD - - - - - - - - - 20 - 75 - true - - - - Search on Global Frequencies Database - -www.qrg.globaltuners.com - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 100 - - - - - - - - - 15 - 75 - true - - - - Search by - - - Qt::AlignCenter - - - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 80 - - - - - - - - Qt::Horizontal - - - - 37 - 20 - - - - - - - - - - - - - 12 - 75 - true - - - - Frequency - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 40 - - - - - - - - - - true - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - - 12 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 100000000 - - - 100 - - - - - - - true - - - - 0 - 0 - - - - - 60 - 0 - - - - - 16777215 - 16777215 - - - - - 12 - 75 - true - - - - - - - MHz - - - 4 - - - false - - - 0 - - - - MHz - - - - - Hz - - - - - kHz - - - - - GHz - - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 20 - - - - - - - - - 15 - 75 - true - - - - Search - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 12 - 75 - true - - - - Location/Callsign - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 40 - - - - - - - - - 12 - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 20 - 20 - - - - - - - - - 15 - 75 - true - - - - Search - - - - - - - - - - - Qt::Horizontal - - - - 37 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 34 - - - - - - - - - - - - - - 0 - 0 - - - - - 270 - 0 - - - - - 270 - 575 - - - - - - - - - - - 0 - 0 - - - - -QWidget { - border: 0px; -} -QPushButton { - border: 0px solid gray; - border-color: #1d5eff; - border-radius: 20px; -} - - - - - - false - - - - 0 - 0 - - - - - 16777215 - 10 - - - - - - - 0 - - - false - - - - - - - false - - - - 0 - 0 - - - - - 70 - 70 - - - - - - - false - - - - - - - false - - - - 0 - 0 - - - - - 70 - 70 - - - - - - - false - - - - - - - false - - - - 0 - 0 - - - - - 70 - 70 - - - - - - - - - - - - - - 0 - 0 - - - - - 20 - 20 - - - - - - - themes/1-default/icons/volume.png - - - true - - - - - - - QSlider::groove:horizontal { - /*border: 1px solid #999999;*/ - height: 6px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */ - background: #7a7a7a; - margin: 0 5px; - border-radius: 3px -} - -QSlider::handle:horizontal { - background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 gray, stop:0.5 white, stop:1.0 gray); - border: 1px solid #5c5c5c; - width: 15px; - margin: -5px -5px; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ - border-radius: 8px; -} - - - - 0 - - - 100 - - - 10 - - - 50 - - - Qt::Horizontal - - - - - - - - - - - - - 0 - 0 - - - - - 250 - 417 - - - - Signal waterfall - - - - - - - - - themes/1-system/icons/nosignalselected.png - - - true - - - - - - - - - - - - 0 - 0 - 1206 - 21 - - - - - - - - - - - File - - - - - - Updates - - - - - - - Themes - - - - - - - - - color: rgb(255, 255, 255); - - - - - Exit - - - - - Update database - - - - - Check latest database version - - - - - - DoubleTextButton - QPushButton -
double_text_button.h
-
-
- - - - -
diff --git a/space_weather_data.py b/space_weather_data.py new file mode 100644 index 0000000..3f6191d --- /dev/null +++ b/space_weather_data.py @@ -0,0 +1,66 @@ +from PyQt5.QtGui import QPixmap +from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject +from threads import UpadteSpaceWeatherThread, ThreadStatus + +class SpaceWeatherData(QObject): + update_complete = pyqtSignal(bool) + + def __init__(self): + super().__init__() + self.xray = '' + self.prot_el = '' + self.ak_index = '' + self.sgas = '' + self.geo_storm = '' + self.images = [QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap()] + self.__update_thread = UpadteSpaceWeatherThread(self) + self.__update_thread.finished.connect(self.__parse_and_emit_signal) + + @property + def is_updating(self): + return self.__update_thread.isRunning() + + @pyqtSlot() + def update(self): + self.__update_thread.start() + + def __parse_data(self): + double_split = lambda string : [i.split() for i in string.splitlines()] + self.xray = double_split(self.xray) + self.prot_el = double_split(self.prot_el) + self.ak_index = double_split(self.ak_index) + self.sgas = double_split(self.sgas) + self.geo_storm = double_split(self.geo_storm) + + def remove_data(self): + self.xray = '' + self.prot_el = '' + self.ak_index = '' + self.sgas = '' + self.geo_storm = '' + self.images = [QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap(), + QPixmap()] + + @pyqtSlot() + def __parse_and_emit_signal(self): + if self.__update_thread.status is not ThreadStatus.OK: + status_ok = False + else: + status_ok = True + self.__parse_data() + self.update_complete.emit(status_ok) diff --git a/switchable_label.py b/switchable_label.py new file mode 100644 index 0000000..c4f6f12 --- /dev/null +++ b/switchable_label.py @@ -0,0 +1,56 @@ +from PyQt5.QtWidgets import QLabel + +class SwitchableLabel(QLabel): + def __init__(self, parent = None): + super().__init__(parent) + self.switch_on_colors = () + self.switch_off_colors = () + self.text_color = '' + self.is_on = False + + def switch_on(self): + self.is_on = True + self.__apply_colors(*self.switch_on_colors) + + def switch_off(self): + self.is_on = False + self.__apply_colors(*self.switch_off_colors) + + def __apply_colors(self, start, end): + self.setStyleSheet( + f""" + color:{self.text_color}; + background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,stop:0 {start} ,stop: 1 {end}); + """ + ) + + +class SwitchableLabelsIterable(object): + def __init__(self, *labels): + self.labels = labels + + def __iter__(self): + for lab in self.labels: + yield lab + + def switch_on(self, label): + for lab in self.labels: + if lab is label: + lab.switch_on() + else: + lab.switch_off() + + def switch_off_all(self): + for lab in self.labels: + lab.switch_off() + + def set(self, attr, value): + for lab in self.labels: + setattr(lab, attr, value) + + def refresh(self): + for lab in self.labels: + if lab.is_on: + lab.switch_on() + else: + lab.switch_off() diff --git a/themes.py b/themes.py index a1603c4..2e7bfa8 100644 --- a/themes.py +++ b/themes.py @@ -1,10 +1,13 @@ from functools import partial +from itertools import chain import os -from PyQt5.QtWidgets import QAction +import re +from PyQt5.QtWidgets import QAction, QActionGroup from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QPixmap from constants import Constants -from utilities import pop_up, is_valid_html_color +from switchable_label import SwitchableLabelsIterable +from utilities import pop_up class ThemeConstants(object): FOLDER = "themes" @@ -14,8 +17,11 @@ class ThemeConstants(object): CURRENT = ".current_theme" COLORS = "colors.txt" COLOR_SEPARATOR = "=" - DEFAULT_ACTIVE_COLOR = "#39eaff" + DEFAULT_ACTIVE_COLOR = "#000000" DEFAULT_INACTIVE_COLOR = "#9f9f9f" + DEFAULT_OFF_COLORS = "#000000", "#434343" + DEFAULT_ON_COLORS = "#4b79a1", "#283e51" + DEFAULT_TEXT_COLOR = "#ffffff" THEME_NOT_FOUND = "Theme not found" MISSING_THEME = "Missing theme in '" + FOLDER + "' folder." @@ -24,10 +30,26 @@ class Theme(object): self.__parent = parent self.__parent.active_color = ThemeConstants.DEFAULT_ACTIVE_COLOR self.__parent.inactive_color = ThemeConstants.DEFAULT_INACTIVE_COLOR - self.__theme_path = ThemeConstants.DEFAULT + + self.__theme_path = "" + self.__current_theme = "" + self.__parent.default_images_folder = os.path.join(ThemeConstants.FOLDER, ThemeConstants.DEFAULT, ThemeConstants.ICONS_FOLDER) + + self.__forecast_labels = SwitchableLabelsIterable(*list(chain(self.__parent.switchable_r_labels, + self.__parent.switchable_s_labels, + self.__parent.switchable_g_now_labels, + self.__parent.switchable_g_today_labels, + self.__parent.k_storm_labels, + self.__parent.a_storm_labels, + [self.__parent.expected_noise_lbl]))) + + self.__forecast_labels.set("switch_on_colors", ThemeConstants.DEFAULT_ON_COLORS) + self.__forecast_labels.set("switch_off_colors", ThemeConstants.DEFAULT_OFF_COLORS) + + self.__theme_names = {} self.__detect_themes() def __refresh_range_labels(self): @@ -41,6 +63,7 @@ class Theme(object): self.__parent.upper_band_filter_unit, self.__parent.upper_band_confidence, self.__parent.band_range_lbl) + self.__parent.set_band_filter_label(self.__parent.activate_low_freq_filter_btn, self.__parent.lower_freq_spinbox, self.__parent.lower_freq_filter_unit, @@ -54,26 +77,33 @@ class Theme(object): @pyqtSlot() def __apply(self, theme_path): self.__theme_path = theme_path - self.__change() - self.__parent.display_specs(self.__parent.result_list.currentItem(), None) - self.__refresh_range_labels() - self.__parent.audio_widget.refresh_btns_colors(self.__parent.active_color, self.__parent.inactive_color) + if self.__theme_path != self.__current_theme: + self.__change() + self.__parent.display_specs(self.__parent.result_list.currentItem(), None) + self.__refresh_range_labels() + self.__parent.audio_widget.refresh_btns_colors(self.__parent.active_color, self.__parent.inactive_color) + self.__forecast_labels.refresh() + + def __pretty_name(self, bad_name): + return ' '.join( + map(lambda s: s.capitalize(), + bad_name.split('-')[1].split('_') + ) + ) def __detect_themes(self): themes = [] + ag = QActionGroup(self.__parent, exclusive = True) for theme_folder in os.listdir(ThemeConstants.FOLDER): relative_folder = os.path.join(ThemeConstants.FOLDER, theme_folder) if os.path.isdir(os.path.abspath(relative_folder)): relative_folder = os.path.join(ThemeConstants.FOLDER, theme_folder) themes.append(relative_folder) for theme_path in themes: - theme_name = '&' + ' '.join( - map(lambda s: s.capitalize(), - os.path.basename(theme_path).split('-')[1].split('_') - ) - ) - new_theme = QAction(theme_name, self.__parent) + theme_name = '&' + self.__pretty_name(os.path.basename(theme_path)) + new_theme = ag.addAction(QAction(theme_name, self.__parent, checkable = True)) self.__parent.menu_themes.addAction(new_theme) + self.__theme_names[theme_name.lstrip('&')] = new_theme new_theme.triggered.connect(partial(self.__apply, theme_path)) def __change(self): @@ -128,27 +158,53 @@ class Theme(object): path_to_colors = os.path.join(self.__theme_path, ThemeConstants.COLORS) active_color_ok = False inactive_color_ok = False - valid_format = False - valid_file = False + switch_on_color_ok = False + switch_off_color_ok = False + text_color_ok = False + if os.path.exists(path_to_colors): - valid_file = True + is_valid_html_color = lambda colors : all([bool(re.match("#([a-zA-Z0-9]){6}", color)) for color in colors]) with open(path_to_colors, "r") as colors_file: for line in colors_file: if ThemeConstants.COLOR_SEPARATOR in line: - valid_format = True quality, color = line.split(ThemeConstants.COLOR_SEPARATOR) color = color.rstrip() - if quality.lower() == Constants.ACTIVE and is_valid_html_color(color): - self.__parent.active_color = color - active_color_ok = True - if quality.lower() == Constants.INACTIVE and is_valid_html_color(color): - self.__parent.inactive_color = color - inactive_color_ok = True + if ',' in color: + color = [c.rstrip().lstrip() for c in color.split(',')] + else: + color = [color] + if len(color) > 2: + break + if is_valid_html_color(color): + if quality.lower() == Constants.ACTIVE: + self.__parent.active_color = color[0] + active_color_ok = True + if quality.lower() == Constants.INACTIVE: + self.__parent.inactive_color = color[0] + inactive_color_ok = True + if len(color) == 2: + if quality.lower() == Constants.LABEL_ON_COLOR: + switch_on_color_ok = True + self.__forecast_labels.set("switch_on_colors", color) + if quality.lower() == Constants.LABEL_OFF_COLOR: + switch_off_color_ok = True + self.__forecast_labels.set("switch_off_colors", color) + if quality.lower() == Constants.TEXT_COLOR: + text_color_ok = True + self.__forecast_labels.set("text_color", color[0]) - if not all([valid_file, valid_format, active_color_ok, inactive_color_ok]): + if not (active_color_ok and inactive_color_ok): self.__parent.active_color = ThemeConstants.DEFAULT_ACTIVE_COLOR self.__parent.inactive_color = ThemeConstants.DEFAULT_INACTIVE_COLOR + if not (switch_on_color_ok and switch_off_color_ok): + self.__forecast_labels.set("switch_on_colors", ThemeConstants.DEFAULT_ON_COLORS) + self.__forecast_labels.set("switch_off_colors", ThemeConstants.DEFAULT_OFF_COLORS) + + if not text_color_ok: + self.__forecast_labels.set("text_color", ThemeConstants.DEFAULT_TEXT_COLOR) + self.__current_theme = self.__theme_path + try: with open(os.path.join(ThemeConstants.FOLDER, ThemeConstants.CURRENT), "w") as current_theme: @@ -161,5 +217,9 @@ class Theme(object): if os.path.exists(current_theme_file): with open(current_theme_file, "r") as current_theme_path: theme_path = current_theme_path.read() - if theme_path != ThemeConstants.DEFAULT: - self.__apply(theme_path) + theme_name = self.__pretty_name(os.path.basename(theme_path)) + self.__theme_names[theme_name].setChecked(True) + self.__apply(theme_path) + else: + self.__theme_names[self.__pretty_name(ThemeConstants.DEFAULT)].setChecked(True) + self.__apply(os.path.join(ThemeConstants.FOLDER, ThemeConstants.DEFAULT)) diff --git a/themes/2-dark/colors.txt b/themes/2-dark/colors.txt index 6050d7d..784707f 100644 --- a/themes/2-dark/colors.txt +++ b/themes/2-dark/colors.txt @@ -1,2 +1,5 @@ -active=#4da6ff +active=#4545e5 inactive=#546E7A +off=#283048,#859398 +on=#4776e6, #8e54e9 +text=#ffffff diff --git a/themes/2-dark/dark.qss b/themes/2-dark/dark.qss index cdc3f79..bece62f 100644 --- a/themes/2-dark/dark.qss +++ b/themes/2-dark/dark.qss @@ -137,7 +137,7 @@ QLabel { QDialog { background-color: transparent; color: #949a9c; -} +} QTextBrowser { background-color: transparent; @@ -157,15 +157,15 @@ QLineEdit { QLineEdit:hover { border-width: 1px; border-radius: 10px; - border-style: solid; - border-color: #4545e5 ; + border-style: solid; + border-color: #4545e5 ; } QLineEdit:focus { border-width: 1px; border-radius: 10px; - border-style: solid; - border-color: #4545e5 ; + border-style: solid; + border-color: #4545e5 ; } /************************************* @@ -307,7 +307,7 @@ QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 20px; - border-top-right-radius: 2px; + border-top-right-radius: 2px; border-bottom-right-radius: 2px; } @@ -433,6 +433,7 @@ TreeViewMenu (Mode) QTreeView { background-color: transparent; selection-background-color: transparent; + border: 0px; } QTreeView::item { diff --git a/themes/3-material_design_dark/colors.txt b/themes/3-material_design_dark/colors.txt index 7c4ba0a..40ab6c1 100644 --- a/themes/3-material_design_dark/colors.txt +++ b/themes/3-material_design_dark/colors.txt @@ -1,2 +1,4 @@ active=#88cc00 inactive=#546E7A +off=#304352,#d7d2cc +on=#3ca55c,#b5ac49 diff --git a/themes/3-material_design_dark/material_design_dark.qss b/themes/3-material_design_dark/material_design_dark.qss index bdfe948..86f5544 100644 --- a/themes/3-material_design_dark/material_design_dark.qss +++ b/themes/3-material_design_dark/material_design_dark.qss @@ -158,7 +158,7 @@ QLabel { QDialog { background-color: transparent; color: #949a9c; -} +} QTextBrowser { background-color: transparent; @@ -172,19 +172,19 @@ QLineEdit { background-color: transparent; selection-background-color: #669900; color: #669900; - border-width: 1px; - border-style: solid; - border-color: transparent transparent #669900 transparent; + border-width: 1px; + border-style: solid; + border-color: transparent transparent #669900 transparent; } QLineEdit:hover { - border-width: 2px; - border-color: transparent transparent #88cc00 transparent; + border-width: 2px; + border-color: transparent transparent #88cc00 transparent; } QLineEdit:focus { - border-width: 2px; - border-color: transparent transparent #88cc00 transparent; + border-width: 2px; + border-color: transparent transparent #88cc00 transparent; } /************************************* @@ -326,7 +326,7 @@ QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 20px; - border-top-right-radius: 2px; + border-top-right-radius: 2px; border-bottom-right-radius: 2px; } @@ -452,6 +452,7 @@ TreeViewMenu (Mode) QTreeView { background-color: transparent; selection-background-color: transparent; + border: 0px; } QTreeView::item { diff --git a/themes/4-material_design_light/colors.txt b/themes/4-material_design_light/colors.txt index c1bccbe..29e38f6 100644 --- a/themes/4-material_design_light/colors.txt +++ b/themes/4-material_design_light/colors.txt @@ -1,2 +1,4 @@ active=#6ECE12 inactive=#b3b3cc +off=#948e99,#2e1437 +on=#b993d6,#8ca6db diff --git a/themes/4-material_design_light/material_design_light.qss b/themes/4-material_design_light/material_design_light.qss index f206187..4874c85 100644 --- a/themes/4-material_design_light/material_design_light.qss +++ b/themes/4-material_design_light/material_design_light.qss @@ -158,7 +158,7 @@ QLabel { QDialog { background-color: transparent; color: #29353B; -} +} QTextBrowser { background-color: transparent; @@ -172,19 +172,19 @@ QLineEdit { background-color: transparent; selection-background-color: #669900; color: #669900; - border-width: 1px; - border-style: solid; - border-color: transparent transparent #669900 transparent; + border-width: 1px; + border-style: solid; + border-color: transparent transparent #669900 transparent; } QLineEdit:hover { - border-width: 2px; - border-color: transparent transparent #6ECE12 transparent; + border-width: 2px; + border-color: transparent transparent #6ECE12 transparent; } QLineEdit:focus { - border-width: 2px; - border-color: transparent transparent #6ECE12 transparent; + border-width: 2px; + border-color: transparent transparent #6ECE12 transparent; } /************************************* @@ -326,7 +326,7 @@ QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 20px; - border-top-right-radius: 2px; + border-top-right-radius: 2px; border-bottom-right-radius: 2px; } @@ -452,6 +452,7 @@ TreeViewMenu (Mode) QTreeView { background-color: transparent; selection-background-color: transparent; + border: 0px; } QTreeView::item { diff --git a/threads.py b/threads.py index d18ce53..50a6c0d 100644 --- a/threads.py +++ b/threads.py @@ -8,18 +8,18 @@ from zipfile import ZipFile from PyQt5.QtCore import QThread from constants import Constants, Database, ChecksumWhat from utilities import checksum_ok -import constants class ThreadStatus(Enum): OK = auto() NO_CONNECTION_ERR = auto() UNKNOWN_ERR = auto() BAD_DOWNLOAD_ERR = auto() + UNDEFINED = auto() class DownloadThread(QThread): def __init__(self): super().__init__() - self.__status = ThreadStatus.OK + self.__status = ThreadStatus.UNDEFINED self.reason = 0 @property @@ -33,8 +33,6 @@ class DownloadThread(QThread): def run(self): try: db = urllib3.PoolManager().request('GET', Database.LINK_LOC) - # db = urllib.request.urlopen(constants.Database.LINK_LOC) - # raise urllib.error.URLError('Test') except urllib3.exceptions.MaxRetryError: # No internet connection. self.__status = ThreadStatus.NO_CONNECTION_ERR return @@ -54,8 +52,45 @@ class DownloadThread(QThread): if os.path.exists(Constants.DATA_FOLDER): rmtree(Constants.DATA_FOLDER) try: - # data_folder = db.read() with ZipFile(BytesIO(db.data)) as zipped: zipped.extractall() except: self.__status = ThreadStatus.UNKNOWN_ERR + else: + self.__status = ThreadStatus.OK + + +class UpadteSpaceWeatherThread(QThread): + def __init__(self, space_weather_data): + super().__init__() + self.__status = ThreadStatus.UNDEFINED + self.__space_weather_data = space_weather_data + + @property + def status(self): + return self.__status + + def __del__(self): + self.terminate() + self.wait() + + def run(self): + try: + self.__space_weather_data.xray = str(urllib3.PoolManager().request('GET', Constants.FORECAST_XRAY).data, 'utf-8') + self.__space_weather_data.prot_el = str(urllib3.PoolManager().request('GET', Constants.FORECAST_PROT).data, 'utf-8') + self.__space_weather_data.ak_index = str(urllib3.PoolManager().request('GET', Constants.FORECAST_AK_IND).data, 'utf-8') + self.__space_weather_data.sgas = str(urllib3.PoolManager().request('GET', Constants.FORECAST_SGAS).data, 'utf-8') + self.__space_weather_data.geo_storm = str(urllib3.PoolManager().request('GET', Constants.FORECAST_G).data, 'utf-8') + self.__space_weather_data.images[0].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_0).data) + self.__space_weather_data.images[1].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_1).data) + self.__space_weather_data.images[2].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_2).data) + self.__space_weather_data.images[3].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_3).data) + self.__space_weather_data.images[4].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_4).data) + self.__space_weather_data.images[5].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_5).data) + self.__space_weather_data.images[6].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_6).data) + self.__space_weather_data.images[7].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_7).data) + self.__space_weather_data.images[8].loadFromData(urllib3.PoolManager().request('GET', Constants.FORECAST_IMG_8).data) + except: + self.__status = ThreadStatus.UNKNOWN_ERR + else: + self.__status = ThreadStatus.OK diff --git a/utilities.py b/utilities.py index de0b8d9..7401e24 100644 --- a/utilities.py +++ b/utilities.py @@ -1,6 +1,5 @@ from functools import partial import hashlib -import re import sys import os from pandas import read_csv @@ -42,9 +41,9 @@ def pop_up(cls, title, text, def checksum_ok(data, what): code = hashlib.sha256() code.update(data) - if what == ChecksumWhat.FOLDER: + if what is ChecksumWhat.FOLDER: n = 0 - elif what == ChecksumWhat.DB: + elif what is ChecksumWhat.DB: n = 1 else: raise ValueError("Wrong entry name.") @@ -55,9 +54,6 @@ def checksum_ok(data, what): raise return code.hexdigest() == reference -def is_valid_html_color(color): - return bool(re.match("#([a-zA-Z0-9]){6}", color)) - def connect_to(events_to_connect, fun_to_connect, fun_args): if fun_args: for event in events_to_connect: @@ -101,8 +97,12 @@ def format_numbers(lower, upper): upper = int(upper) / upper_factor if lower.is_integer(): lower = int(lower) + else: + lower = round(lower, 2) if upper.is_integer(): upper = int(upper) + else: + upper = round(upper, 2) if pre_lower != pre_upper: return f"{lower:,} {units[lower_factor]} - {upper:,} {units[upper_factor]}" else: