diff --git a/.gitignore b/.gitignore
index c158ac8..660e8c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ wav_converter.py
*.txt
icons_imgs
TestData
+themes/.current_theme
diff --git a/audio_player.py b/audio_player.py
index 27754e7..2d4c2f5 100644
--- a/audio_player.py
+++ b/audio_player.py
@@ -3,9 +3,9 @@ import sys
from pydub import AudioSegment
from pygame import mixer
from PyQt5.QtCore import QTimer, QTimer, pyqtSlot, QObject
-import qtawesome as qta
from utilities import Constants
+import qtawesome as qta
class AudioPlayer(QObject): # Maybe useless inheriting from QObject
@@ -17,7 +17,7 @@ class AudioPlayer(QObject): # Maybe useless inheriting from QObject
__time_step = 500 # Milliseconds.
- def __init__(self, play, pause, stop, volume, audio_progress):
+ def __init__(self, play, pause, stop, volume, audio_progress, active_color, inactive_color):
super().__init__()
self.__paused = False
self.__first_call = True
@@ -33,18 +33,21 @@ class AudioPlayer(QObject): # Maybe useless inheriting from QObject
self.__pause.clicked.connect(self.__pause_audio)
self.__stop.clicked.connect(self.__stop_audio)
self.__volume.valueChanged.connect(self.__set_volume)
- self.__play.setIcon(qta.icon('fa5.play-circle',
- color = "#4facf1",
- color_disabled = '#7a7a7a'))
self.__play.setIconSize(self.__play.size())
- self.__pause.setIcon(qta.icon('fa5.pause-circle',
- color = "#4facf1",
- color_disabled = '#7a7a7a'))
self.__pause.setIconSize(self.__pause.size())
- self.__stop.setIcon(qta.icon('fa5.stop-circle',
- color = "#4facf1",
- color_disabled = '#7a7a7a'))
self.__stop.setIconSize(self.__stop.size())
+ self.refresh_btns_colors(active_color, inactive_color)
+
+ def refresh_btns_colors(self, active_color, inactive_color):
+ self.__play.setIcon(qta.icon('fa5.play-circle',
+ color = active_color,
+ color_disabled = inactive_color))
+ self.__pause.setIcon(qta.icon('fa5.pause-circle',
+ color = active_color,
+ color_disabled = inactive_color))
+ self.__stop.setIcon(qta.icon('fa5.stop-circle',
+ color = active_color,
+ color_disabled = inactive_color))
@pyqtSlot()
def __set_volume(self):
diff --git a/download_db_window.ui b/download_db_window.ui
index 2f17663..6f3c1f8 100644
--- a/download_db_window.ui
+++ b/download_db_window.ui
@@ -14,33 +14,7 @@
Download database
- QWidget {
- background-color: #464646
-}
-
-QLabel {
- color: #ffffff;
-}
-
-QProgressBar {
- border: 2px #7a7a7a;
- border-radius: 5px;
- background-color: #7a7a7a;
-}
-
-QProgressBar::chunk {
- background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
- border-radius: 5px;
-}
-
-
-QMessageBox {
- color: #ffffff;
-}
-
-QPushButton {
- color: #ffffff;
-}
+
@@ -73,6 +47,9 @@ Please wait
-1
+
+ false
+
-
@@ -83,13 +60,7 @@ Please wait
- QPushButton {
- background-color: rgb(52,52,52);
- color: #FFFFFF;
- border: 1px solid gray;
- border-radius: 8px;
-}
-
+
Cancel
diff --git a/main.py b/main.py
index 1c584ff..7a14016 100644
--- a/main.py
+++ b/main.py
@@ -1,5 +1,6 @@
from collections import namedtuple
from functools import partial
+from glob import glob
import webbrowser
import os
import sys
@@ -7,12 +8,13 @@ import sys
from pandas import read_csv
from PyQt5.QtWidgets import (QMainWindow,
QApplication,
+ QAction,
QMessageBox,
qApp,
QDesktopWidget,
QListWidgetItem,
QTreeView,
- QTreeWidgetItem)
+ QTreeWidgetItem,)
from PyQt5.QtGui import QPixmap
from PyQt5 import uic
from PyQt5.QtCore import (QFileInfo,
@@ -24,7 +26,12 @@ from audio_player import AudioPlayer
from double_text_button import DoubleTextButton
from download_window import DownloadWindow
-from utilities import Constants, reset_apply_remove_btn
+
+
+from utilities import (Constants,
+ reset_apply_remove_btn,
+ throwable_message,
+ is_valid_html_color,)
qt_creator_file = "main_window.ui"
Ui_MainWindow, _ = uic.loadUiType(qt_creator_file)
@@ -42,6 +49,8 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.current_signal_name = ''
self.signal_names = []
self.total_signals = 0
+ self.active_color = Constants.ACTIVE_COLOR
+ self.inactive_color = Constants.INACTIVE_COLOR
# Manage frequency filters.
self.frequency_filters_btns = (
@@ -301,6 +310,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.reset_location_filters_btn.clicked.connect(self.reset_location_filters)
self.locations_list.itemClicked.connect(self.remove_if_unselected_location)
+ # Find available themes.
+ self.default_images_folder = os.path.join(Constants.THEMES_FOLDER,
+ Constants.DEFAULT_THEME,
+ Constants.ICONS_FOLDER)
+ # self.find_themes()
+ # self.set_theme()
+
# ##########################################################################################
self.load_db()
@@ -309,16 +325,15 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.search_bar.textChanged.connect(self.display_signals)
self.result_list.addItems(self.signal_names)
self.result_list.currentItemChanged.connect(self.display_specs)
- self.result_list.itemDoubleClicked.connect(lambda: self.main_tab.setCurrentWidget(
- self.signal_properties_tab
- )
- )
+ 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,
self.volume,
- self.audio_progress)
+ self.audio_progress,
+ self.active_color,
+ self.inactive_color)
BandLabel = namedtuple("BandLabel", ["left", "center", "right"])
self.band_labels = [
@@ -334,8 +349,124 @@ class MyApp(QMainWindow, Ui_MainWindow):
BandLabel(self.shf_left, self.shf, self.shf_right),
BandLabel(self.ehf_left, self.ehf, self.ehf_right),
]
+
+ self.find_themes()
+ self.set_theme()
+
self.show()
+ def find_themes(self):
+ themes = []
+ for theme_folder in os.listdir(Constants.THEMES_FOLDER):
+ relative_folder = os.path.join(Constants.THEMES_FOLDER, theme_folder)
+ if os.path.isdir(os.path.abspath(relative_folder)):
+ relative_folder = os.path.join(Constants.THEMES_FOLDER, theme_folder)
+ themes.append(relative_folder)
+ for theme in themes:
+ theme_name = '&' + ' '.join(
+ map(lambda s: s.capitalize(),
+ os.path.basename(theme).split('-')[1].split('_')
+ )
+ )
+ new_theme = QAction(theme_name, self)
+ self.menu_themes.addAction(new_theme)
+
+ @pyqtSlot()
+ def show_new_theme(theme):
+ self.change_theme(theme)
+ self.display_specs(self.result_list.currentItem(), None)
+ new_theme.triggered.connect(partial(show_new_theme, theme))
+
+ @pyqtSlot()
+ def change_theme(self, theme_path):
+ try:
+ with open(os.path.join(
+ theme_path,
+ os.path.basename(theme_path).split('-')[1] + Constants.THEME_EXTENSION)
+ ) as stylesheet:
+ style = stylesheet.read()
+ self.setStyleSheet(style)
+ self.download_window.setStyleSheet(style)
+ except FileNotFoundError:
+ throwable_message(self, title = "Theme not found",
+ text = f"Missing theme in {Constants.THEMES_FOLDER} folder.").show()
+ else:
+ icons_path = os.path.join(theme_path, Constants.ICONS_FOLDER)
+ default_icons_path = os.path.join(Constants.THEMES_FOLDER, Constants.DEFAULT_THEME, Constants.ICONS_FOLDER)
+
+ if os.path.exists(os.path.join(icons_path, Constants.NOT_SELECTED)) and \
+ os.path.exists(os.path.join(icons_path, Constants.NOT_AVAILABLE)):
+ self.default_images_folder = icons_path
+ else:
+ self.default_images_folder = default_icons_path
+
+ path_to_search_label = os.path.join(icons_path, Constants.SEARCH_LABEL_IMG)
+ default_search_label = os.path.join(default_icons_path, Constants.SEARCH_LABEL_IMG)
+
+ if os.path.exists(path_to_search_label):
+ self.search_label.setPixmap(QPixmap(path_to_search_label))
+ self.modulation_search_label.setPixmap(QPixmap(path_to_search_label))
+ self.location_search_label.setPixmap(QPixmap(path_to_search_label))
+ else:
+ self.search_label.setPixmap(QPixmap(default_search_label))
+ self.modulation_search_label.setPixmap(QPixmap(default_search_label))
+ self.location_search_label.setPixmap(QPixmap(default_search_label))
+
+ self.search_label.setScaledContents(True)
+ self.modulation_search_label.setScaledContents(True)
+ self.location_search_label.setScaledContents(True)
+
+ path_to_volume_label = os.path.join(icons_path, Constants.VOLUME_LABEL_IMG)
+ default_volume_label = os.path.join(default_icons_path, Constants.VOLUME_LABEL_IMG)
+
+ if os.path.exists(path_to_volume_label):
+ self.volume_label.setPixmap(QPixmap(path_to_volume_label))
+ else:
+ self.volume_label.setPixmap(QPixmap(default_volume_label))
+
+ self.volume_label.setScaledContents(True)
+
+ path_to_colors = os.path.join(theme_path, Constants.THEME_COLORS)
+ active_color_ok = False
+ inactive_color_ok = False
+ valid_format = False
+ valid_file = False
+ if os.path.exists(path_to_colors):
+ valid_file = True
+ with open(path_to_colors, "r") as colors_file:
+ for line in colors_file:
+ if '=' in line:
+ valid_format = True
+ quality, color = line.split("=")
+ color = color.rstrip()
+ if quality == "active" and is_valid_html_color(color):
+ self.active_color = color
+ active_color_ok = True
+ if quality == "inactive" and is_valid_html_color(color):
+ self.inactive_color = color
+ inactive_color_ok = True
+
+ if not all([valid_file, valid_format, active_color_ok, inactive_color_ok]):
+ self.active_color = Constants.ACTIVE_COLOR
+ self.inactive_color = Constants.INACTIVE_COLOR
+
+ self.audio_widget.refresh_btns_colors(self.active_color, self.inactive_color)
+
+ try:
+ with open(os.path.join(Constants.THEMES_FOLDER,
+ Constants.CURRENT_THEME), "w") as current_theme:
+ current_theme.write(theme_path)
+ except:
+ pass
+
+ def set_theme(self):
+ current_theme_file = os.path.join(Constants.THEMES_FOLDER, Constants.CURRENT_THEME)
+ if os.path.exists(current_theme_file):
+ with open(current_theme_file) as current_theme:
+ theme = current_theme.read()
+ if theme != Constants.DEFAULT_THEME:
+ self.change_theme(theme)
+
@pyqtSlot(QListWidgetItem)
def remove_if_unselected_modulation(self, item):
if not item.isSelected():
@@ -440,42 +571,25 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.display_signals()
def load_db(self):
- names = ["name",
- "inf_freq",
- "sup_freq",
- "mode",
- "inf_band",
- "sup_band",
- "location",
- "url",
- "description",
- "modulation",
- "category_code",
- "acf",]
+ names = Constants.DB_NAMES
try:
- self.db = read_csv(os.path.join(Constants.DATA_FOLDER, 'db.csv'),
+ self.db = read_csv(os.path.join(Constants.DATA_FOLDER, Constants.DB_NAME),
sep = '*',
header = None,
index_col = 0,
- dtype = {'inf_freq': str,
- 'sup_freq': str,
- 'mode': str,
- 'inf_band': str,
- 'sup_band': str,
- 'category_code': str,},
+ dtype = {name : str for name in Constants.DB_STRINGS},
names = names,)
except FileNotFoundError:
self.search_bar.setDisabled(True)
box = QMessageBox(self)
- box.setWindowTitle("No database")
- box.setText("No database available.\n"
- "Go to Updates->Update database.")
+ box.setWindowTitle(Constants.Messages.NO_DB)
+ box.setText(Constants.Messages.NO_DB_AVAIL)
box.show()
else:
self.signal_names = self.db.index
self.total_signals = len(self.signal_names)
self.db.fillna(Constants.UNKNOWN, inplace = True)
- self.db["url_clicked"] = False
+ self.db[Constants.DB_WIKI_CLICKED] = False
self.update_status_tip(self.total_signals)
@staticmethod
@@ -530,13 +644,13 @@ class MyApp(QMainWindow, Ui_MainWindow):
range_lbl):
activate_low = False
activate_high = False
- color = Constants.INACTIVE_COLOR
+ color = self.inactive_color
title = ''
to_display = ''
if activate_low_btn.isChecked():
to_display += str(lower_spinbox.value()) + ' ' + lower_unit.currentText()
activate_low = True
- color = Constants.ACTIVE_COLOR
+ color = self.active_color
if lower_confidence.value() != 0:
to_display += ' - ' + str(lower_confidence.value()) + ' %'
else:
@@ -545,7 +659,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
if activate_up_btn.isChecked():
to_display += str(upper_spinbox.value()) + ' ' + upper_unit.currentText()
activate_high = True
- color = Constants.ACTIVE_COLOR
+ color = self.active_color
if upper_confidence.value() != 0:
to_display += ' + ' + str(upper_confidence.value()) + ' %'
else:
@@ -591,7 +705,7 @@ class MyApp(QMainWindow, Ui_MainWindow):
def update_status_tip(self, available_signals):
if available_signals < self.total_signals:
- self.statusbar.setStyleSheet(f'color: {Constants.ACTIVE_COLOR}')
+ self.statusbar.setStyleSheet(f'color: {self.active_color}')
else:
self.statusbar.setStyleSheet('color: #ffffff')
self.statusbar.showMessage(f"{available_signals} out of {self.total_signals} signals displayed.")
@@ -821,21 +935,21 @@ class MyApp(QMainWindow, Ui_MainWindow):
self.description_text.setText(current_signal.at["description"])
for cat, cat_lab in zip(category_code, self.category_labels):
if cat == '0':
- cat_lab.setStyleSheet(f"color: {Constants.INACTIVE_COLOR};")
+ cat_lab.setStyleSheet(f"color: {self.inactive_color};")
elif cat == '1':
- cat_lab.setStyleSheet(f"color: {Constants.ACTIVE_COLOR};")
+ cat_lab.setStyleSheet(f"color: {self.active_color};")
self.set_band_range(current_signal)
self.audio_widget.set_audio_player(self.current_signal_name)
else:
self.url_button.setEnabled(False)
self.url_button.setStyleSheet(f"color: {self.url_button.colors.inactive};")
self.current_signal_name = ''
- self.name_lab.setText("No signal")
+ self.name_lab.setText("No Signal")
self.name_lab.setAlignment(Qt.AlignHCenter)
for lab in self.property_labels:
lab.setText(Constants.UNKNOWN)
for lab in self.category_labels:
- lab.setStyleSheet(f"color: {Constants.INACTIVE_COLOR};")
+ lab.setStyleSheet(f"color: {self.inactive_color};")
self.set_band_range()
self.audio_widget.set_audio_player()
@@ -882,23 +996,21 @@ class MyApp(QMainWindow, Ui_MainWindow):
return 10**9
def display_spectrogram(self):
- default_pic = os.path.join(Constants.ICONS_FOLDER, "nosignalselected.png")
+ default_pic = os.path.join(self.default_images_folder, Constants.NOT_SELECTED)
item = self.result_list.currentItem()
if item:
spectrogram_name = item.text()
path_spectr = os.path.join(Constants.DATA_FOLDER,
Constants.SPECTRA_FOLDER,
- spectrogram_name + ".png")
+ spectrogram_name + Constants.SPECTRA_EXT)
if not QFileInfo(path_spectr).exists():
- path_spectr = os.path.join(Constants.ICONS_FOLDER,
- "spectrumnotavailable.png")
+ path_spectr = os.path.join(self.default_images_folder, Constants.NOT_AVAILABLE)
else:
path_spectr = default_pic
self.spectrogram.setPixmap(QPixmap(path_spectr))
- @staticmethod
- def activate_band_category(band_label, activate = True):
- color = Constants.ACTIVE_COLOR if activate else Constants.INACTIVE_COLOR
+ def activate_band_category(self, band_label, activate = True):
+ color = self.active_color if activate else self.inactive_color
for label in band_label:
label.setStyleSheet(f"color: {color};")
diff --git a/main_window.ui b/main_window.ui
index 59ef163..6b9a454 100644
--- a/main_window.ui
+++ b/main_window.ui
@@ -20,135 +20,7 @@
ARTEMIS3
- QWidget {
- background-color: #464646
-}
-
-QLabel {
- color: #ffffff;
-}
-
-QPushButton {
- color: #FFFFFF
-}
-
-QProgressBar {
- border: 2px #7a7a7a;
- border-radius: 3px;
- background-color: #7a7a7a;
-}
-
-QProgressBar::chunk {
- /*background-color: #1d5eff;*/
- background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
- border-radius: 3px;
-}
-
-QAbstractScrollArea::corner {
- background: none;
- border: none;
-}
-
-QScrollBar:vertical, QScrollBar:horizontal{
- background-color:#343434;
- border-radius: 5px;
- /*background: none;*/
-}
-
-QScrollBar:vertical {
- margin-top: 0px;
- margin-bottom: 0px;
- /*width: 10px;*/
-}
-QScrollBar:horizontal{
- margin-left: 0px;
- margin-right: 0px;
- /*height: 10px;*/
-}
-
-QScrollBar::handle:vertical, QScrollBar::handle:horizontal{
- border-radius: 5px;
- border-color: none;
- border-width: 1px;
- background-color: #999999;
-}
-
-QScrollBar::add-line:vertical, QScrollBar::add-line:horizontal{
- width: 0px;
- height: 0px;
-}
-
-QScrollBar::sub-line:vertical, QScrollBar::sub-line:horizontal{
- width: 0px;
- height: 0px;
-}
-
-QScrollBar::add-page:vertical{
- border-left: 1px solid gray;
- background: transparent;
- border-radius: 5px;
-/*
- border: 1px#343434;
- background-color: #343434;*/
-}
-QScrollBar::add-page:horizontal{
- border-top: 1px solid gray;
- background: transparent;
- border-radius: 5px;
-/*
- border: 1px#343434;
- background-color: #343434;*/
-}
-QScrollBar::sub-page:vertical{
- border-left: 1px solid gray;
- background: transparent;
- border-radius: 5px;
-/* border: 1px #343434;
- background-color: #343434;*/
-}
-QScrollBar::sub-page:horizontal{
- border-top: 1px solid gray;
- background: transparent;
- border-radius: 5px;
-/* border: 1px #343434;
- background-color: #343434;*/
-}
-
-QTextEdit{
- color: #ffffff;
-}
-
-QMessageBox {
- color: #ffffff;
-}
-
-QToolTip {
- color: #000000;
-}
-
-QTextBrowser {
- background-color: #464646;
- color: #ffffff;
- border: 0px;
-}
-
-QRadioButton {
- color: #ffffff;
-}
-
-QListWidget {
- background-color:rgb(52,52,52);
- color: rgb(255, 255, 255);
- border: 1px solid gray;
- border-radius: 8px;
-}
-
-QLineEdit {
- background-color: #343434;
- color: rgb(255, 255, 255);
- border: 1px solid gray;
- border-radius: 5px;
-}
+
@@ -229,7 +101,7 @@ QLineEdit {
- icons_imgs/search_icon.png
+ themes/1-default/icons/search_icon.png
true
@@ -293,40 +165,7 @@ QLineEdit {
Qt::LeftToRight
- QTabWidget::pane { /* The tab widget frame */
- /* border-left: 1px solid gray;*/
-}
-
-
-QTabWidget::tab-bar {
- left: 30px; /* move to the right by 5px */
-}
-
-
-/* Style the tab using the tab sub-control. Note that
- it reads QTabBar _not_ QTabWidget */
-QTabBar::tab {
- background: #7a7a7a;
- border-top-left-radius: 8px;
- border-top-right-radius: 8px;
- min-width: 16ex;
- padding: 2px;
- color: #FFFFFF
-}
-
-QTabBar::tab:selected {
- background: #999999;
- color: #1d5eff
-}
-
-
-QTabBar::tab:!selected {
- margin-top: 3px; /* make non-selected tabs look smaller */
-}
-
-QPushButton:!enabled {
- color:#9f9f9f;
-}
+
QTabWidget::North
@@ -335,7 +174,7 @@ QPushButton:!enabled {
QTabWidget::Rounded
- 1
+ 0
true
@@ -1221,7 +1060,7 @@ p, li { white-space: pre-wrap; }
<html><head/><body><p><span style=" color:#000000;">Go to the signal's wiki.</span></p></body></html>
- color: #9f9f9f;
+
Signal's wiki
@@ -1929,49 +1768,7 @@ p, li { white-space: pre-wrap; }
-
- QComboBox {
- background-color: rgb(52,52,52);
- color: #ffffff;
- border: 1px solid gray;
- border-radius: 5px;
-}
-
-QComboBox:!enabled {
- color: #9f9f9f;
-}
-
-QComboBox QAbstractItemView {
- border: 1px solid gray;
- selection-background-color: #999999;
- selection-color: #1d5eff;
- color: #ffffff;
-}
-
-QSpinBox {
- background-color: rgb(52,52,52);
- color: #ffffff;
- border: 1px solid gray;
- border-radius: 5px;
-}
-
-QSpinBox:!enabled {
- color:#9f9f9f;
-}
-
-QPushButton {
- background-color: rgb(52,52,52);
- border: 1px solid gray;
- border-radius: 5px;
-}
-
-QPushButton:!enabled {
- color:#9f9f9f;
-}
-
-QPushButton:checked {
- color: #39eaff;
-}
-
+
5
@@ -2262,15 +2059,7 @@ QPushButton:checked {
- QWidget#freq_filter_container {
- border: 1px solid gray;
- background-color: rgb(52,52,52);
- border-radius: 12px;
-}
-
-QRadioButton, QLabel {
- background-color: rgb(52,52,52);
-}
+
-
@@ -2319,7 +2108,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -2363,7 +2152,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
MHz
@@ -2451,7 +2240,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
false
@@ -2519,7 +2308,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -2566,7 +2355,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
MHz
@@ -2645,7 +2434,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
false
@@ -2796,15 +2585,7 @@ Inactive
- QWidget#band_filter_container {
- border: 1px solid gray;
- background-color: rgb(52,52,52);
- border-radius: 12px;
-}
-
-QRadioButton, QLabel {
- background-color: rgb(52,52,52);
-}
+
-
@@ -2836,7 +2617,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -2881,7 +2662,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -2943,7 +2724,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
false
@@ -3019,7 +2800,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
MHz
@@ -3084,7 +2865,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
false
@@ -3137,7 +2918,7 @@ QRadioButton, QLabel {
- background-color: #464646;
+
MHz
@@ -3225,7 +3006,7 @@ QRadioButton, QLabel {
- color: #9f9f9f;
+
Selected range:
@@ -3311,47 +3092,383 @@ Inactive
Category
-
-
-
-
-
- 12
- 75
- true
-
+
-
+
+
+ Qt::Horizontal
-
- <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
+
+
+ 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
+
+
+
+
-
-
-
-
- 12
- 75
- true
-
+
+
+ Qt::Horizontal
-
- <html><head/><body><p>Keep all the signals which belong to <span style=" font-style:italic;">all </span>the selected categories.</p></body></html>
+
+
+ 102
+ 20
+
-
- All selected
-
-
- false
+
+
+ -
+
+
+
+ 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
+
+
+
+
-
@@ -3388,307 +3505,6 @@ Inactive
- -
-
-
-
- 0
- 0
-
-
-
-
-
-
-
-
- 12
- 75
- true
-
-
-
- Military
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Radar
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Active
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Inactive
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- HAM
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Commercial
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Aviation
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Marine
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Analogue
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Digital
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Trunked
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Utility
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Satellite
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Navigation
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Interfering
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Time Signal
-
-
- true
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- Number Stations
-
-
- true
-
-
-
-
-
-
@@ -3838,7 +3654,7 @@ Inactive
-
-
+
0
@@ -3965,7 +3781,7 @@ Inactive
-
-
+
0
@@ -4073,9 +3889,7 @@ Inactive
- background-color: rgb(52,52,52);
-border: 1px solid gray;
-border-radius: 5px;
+
Reset all filters
@@ -4108,25 +3922,7 @@ border-radius: 5px;
- QWidget {
-background-color:rgb(52,52,52);
-border: 1px solid gray;
-border-radius: 8px;
-}
-QProgressBar {
- border: 2px #7a7a7a;
- border-radius: 3px;
- background-color: #7a7a7a;
-}
-
-QProgressBar::chunk {
- /*background-color: #1d5eff;*/
- background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
- border-radius: 3px;
-}
-QLabel, QPushButton, QSlider {
- border: 0px;
-}
+
-
@@ -4143,17 +3939,10 @@ QWidget {
border: 0px;
}
QPushButton {
- /*background-color: #1d5eff;*/
border: 0px solid gray;
border-color: #1d5eff;
border-radius: 20px;
-}
-
-/*
-QPushButton:disabled {
- background-color: #7a7a7a;
-}
-*/
+}
-
@@ -4259,7 +4048,7 @@ QPushButton:disabled {
-
-
-
+
0
@@ -4276,7 +4065,7 @@ QPushButton:disabled {
- icons_imgs/volume.png
+ themes/1-default/icons/volume.png
true
@@ -4349,7 +4138,7 @@ QSlider::handle:horizontal {
- icons_imgs/nosignalselected.png
+ themes/1-system/icons/nosignalselected.png
true
@@ -4371,23 +4160,7 @@ QSlider::handle:horizontal {
- QMenuBar {
- color: rgb(255, 255, 255);
-}
-
-QMenuBar::item:selected {
- background:#999999;
- color: #1d5eff
-}
-
-QMenu::item:selected {
- background-color: #999999;
- color: #1d5eff
-}
-
-QMenu {
- color: #ffffff;
-}
+
+
+
diff --git a/themes/1-system/icons/nosignalselected.png b/themes/1-system/icons/nosignalselected.png
new file mode 100644
index 0000000..a9e40f8
Binary files /dev/null and b/themes/1-system/icons/nosignalselected.png differ
diff --git a/themes/1-system/icons/search_icon.png b/themes/1-system/icons/search_icon.png
new file mode 100644
index 0000000..cc72a1e
Binary files /dev/null and b/themes/1-system/icons/search_icon.png differ
diff --git a/themes/1-system/icons/spectrumnotavailable.png b/themes/1-system/icons/spectrumnotavailable.png
new file mode 100644
index 0000000..2c22abc
Binary files /dev/null and b/themes/1-system/icons/spectrumnotavailable.png differ
diff --git a/themes/1-system/icons/volume.png b/themes/1-system/icons/volume.png
new file mode 100644
index 0000000..5cc5645
Binary files /dev/null and b/themes/1-system/icons/volume.png differ
diff --git a/themes/1-system/system.th b/themes/1-system/system.th
new file mode 100644
index 0000000..e69de29
diff --git a/themes/2-dark/dark.th b/themes/2-dark/dark.th
new file mode 100644
index 0000000..82622f4
--- /dev/null
+++ b/themes/2-dark/dark.th
@@ -0,0 +1,239 @@
+QMenuBar {
+ color: rgb(255, 255, 255);
+}
+
+QMenuBar::item:selected {
+ background:#999999;
+ color: #1d5eff
+}
+
+QMenu::item:selected {
+ background-color: #999999;
+ color: #1d5eff
+}
+
+QMenu {
+ color: #ffffff;
+}
+
+QWidget {
+ background-color: #464646
+}
+
+QLabel {
+ color: #ffffff;
+}
+
+QPushButton {
+ color: #FFFFFF;
+ background-color: rgb(52,52,52);
+ border: 1px solid gray;
+ border-radius: 5px;
+}
+
+QPushButton:!enabled {
+ color:#9f9f9f;
+}
+
+QPushButton:checked {
+ color: #39eaff;
+}
+
+QTabWidget::pane { /* The tab widget frame */
+ /* border-left: 1px solid gray;*/
+ border: 0px;
+}
+
+
+QTabWidget::tab-bar {
+ left: 30px; /* move to the right by 5px */
+}
+
+
+/* Style the tab using the tab sub-control. Note that
+ it reads QTabBar _not_ QTabWidget */
+QTabBar::tab {
+ background: #7a7a7a;
+ border-top-left-radius: 8px;
+ border-top-right-radius: 8px;
+ min-width: 16ex;
+ padding: 2px;
+ color: #FFFFFF
+}
+
+QTabBar::tab:selected {
+ background: #999999;
+ color: #1d5eff
+}
+
+
+QTabBar::tab:!selected {
+ margin-top: 3px; /* make non-selected tabs look smaller */
+}
+
+
+
+QProgressBar {
+ border: 2px #7a7a7a;
+ border-radius: 3px;
+ background-color: #7a7a7a;
+}
+
+QProgressBar::chunk {
+ /*background-color: #1d5eff;*/
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #1d5eff, stop:0.5 #4177ff, stop:1 #1d5eff);
+ border-radius: 3px;
+}
+
+
+QAbstractScrollArea::corner {
+ background: none;
+ border: none;
+}
+
+QScrollBar:vertical, QScrollBar:horizontal{
+ background-color:#343434;
+ border-radius: 5px;
+ /*background: none;*/
+}
+
+QScrollBar:vertical {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ /*width: 10px;*/
+}
+QScrollBar:horizontal{
+ margin-left: 0px;
+ margin-right: 0px;
+ /*height: 10px;*/
+}
+
+QScrollBar::handle:vertical, QScrollBar::handle:horizontal{
+ border-radius: 5px;
+ border-color: none;
+ border-width: 1px;
+ background-color: #999999;
+}
+
+QScrollBar::add-line:vertical, QScrollBar::add-line:horizontal{
+ width: 0px;
+ height: 0px;
+}
+
+QScrollBar::sub-line:vertical, QScrollBar::sub-line:horizontal{
+ width: 0px;
+ height: 0px;
+}
+
+QScrollBar::add-page:vertical{
+ border-left: 1px solid gray;
+ background: transparent;
+ border-radius: 5px;
+/*
+ border: 1px#343434;
+ background-color: #343434;*/
+}
+QScrollBar::add-page:horizontal{
+ border-top: 1px solid gray;
+ background: transparent;
+ border-radius: 5px;
+/*
+ border: 1px#343434;
+ background-color: #343434;*/
+}
+QScrollBar::sub-page:vertical{
+ border-left: 1px solid gray;
+ background: transparent;
+ border-radius: 5px;
+/* border: 1px #343434;
+ background-color: #343434;*/
+}
+QScrollBar::sub-page:horizontal{
+ border-top: 1px solid gray;
+ background: transparent;
+ border-radius: 5px;
+/* border: 1px #343434;
+ background-color: #343434;*/
+}
+
+QTextEdit{
+ color: #ffffff;
+}
+
+QMessageBox {
+ color: #ffffff;
+}
+
+QToolTip {
+ color: #000000;
+}
+
+QTextBrowser {
+ background-color: #464646;
+ color: #ffffff;
+ border: 0px;
+}
+
+QRadioButton {
+ color: #ffffff;
+}
+
+QListWidget {
+ background-color:rgb(52,52,52);
+ color: rgb(255, 255, 255);
+ border: 1px solid gray;
+ border-radius: 8px;
+}
+
+QLineEdit {
+ background-color: #343434;
+ color: rgb(255, 255, 255);
+ border: 1px solid gray;
+ border-radius: 5px;
+}
+
+QComboBox {
+ background-color: rgb(52,52,52);
+ color: #ffffff;
+ border: 1px solid gray;
+ border-radius: 5px;
+}
+
+QComboBox:!enabled {
+ color: #9f9f9f;
+}
+
+QComboBox QAbstractItemView {
+ border: 1px solid gray;
+ selection-background-color: #999999;
+ selection-color: #1d5eff;
+ color: #ffffff;
+}
+
+QSpinBox {
+ background-color: rgb(52,52,52);
+ color: #ffffff;
+ border: 1px solid gray;
+ border-radius: 5px;
+}
+
+QSpinBox:!enabled {
+ color:#9f9f9f;
+}
+
+/* SPECIAL WIDGETS */
+QPushButton#url_button {
+ color: #9f9f9f;
+ border: 0px;
+ background-color: #464646;
+}
+
+QPushButton#play, QPushButton#pause, QPushButton#stop {
+ color: #464646;
+ border: 0px;
+ background-color: #464646;
+}
+
+QLabel#band_range_lbl {
+ color: #9f9f9f;
+}
diff --git a/themes/3-material_design/icons/down-arrow.png b/themes/3-material_design/icons/down-arrow.png
new file mode 100644
index 0000000..b2cd4a5
Binary files /dev/null and b/themes/3-material_design/icons/down-arrow.png differ
diff --git a/themes/3-material_design/icons/down-arrow_hover.png b/themes/3-material_design/icons/down-arrow_hover.png
new file mode 100644
index 0000000..f7ad171
Binary files /dev/null and b/themes/3-material_design/icons/down-arrow_hover.png differ
diff --git a/themes/3-material_design/icons/down-arrow_off.png b/themes/3-material_design/icons/down-arrow_off.png
new file mode 100644
index 0000000..e7f0af3
Binary files /dev/null and b/themes/3-material_design/icons/down-arrow_off.png differ
diff --git a/themes/3-material_design/icons/off.png b/themes/3-material_design/icons/off.png
new file mode 100644
index 0000000..ef39d9e
Binary files /dev/null and b/themes/3-material_design/icons/off.png differ
diff --git a/themes/3-material_design/icons/off_press.png b/themes/3-material_design/icons/off_press.png
new file mode 100644
index 0000000..3355d12
Binary files /dev/null and b/themes/3-material_design/icons/off_press.png differ
diff --git a/themes/3-material_design/icons/on.png b/themes/3-material_design/icons/on.png
new file mode 100644
index 0000000..2244ffe
Binary files /dev/null and b/themes/3-material_design/icons/on.png differ
diff --git a/themes/3-material_design/icons/on_press.png b/themes/3-material_design/icons/on_press.png
new file mode 100644
index 0000000..4754508
Binary files /dev/null and b/themes/3-material_design/icons/on_press.png differ
diff --git a/themes/3-material_design/icons/search_icon.png b/themes/3-material_design/icons/search_icon.png
new file mode 100644
index 0000000..dd0ec52
Binary files /dev/null and b/themes/3-material_design/icons/search_icon.png differ
diff --git a/themes/3-material_design/icons/up-arrow.png b/themes/3-material_design/icons/up-arrow.png
new file mode 100644
index 0000000..6f0f090
Binary files /dev/null and b/themes/3-material_design/icons/up-arrow.png differ
diff --git a/themes/3-material_design/icons/up-arrow_hover.png b/themes/3-material_design/icons/up-arrow_hover.png
new file mode 100644
index 0000000..149eae0
Binary files /dev/null and b/themes/3-material_design/icons/up-arrow_hover.png differ
diff --git a/themes/3-material_design/icons/up-arrow_off.png b/themes/3-material_design/icons/up-arrow_off.png
new file mode 100644
index 0000000..ac2217f
Binary files /dev/null and b/themes/3-material_design/icons/up-arrow_off.png differ
diff --git a/themes/3-material_design/icons/volume.png b/themes/3-material_design/icons/volume.png
new file mode 100644
index 0000000..88e4c7e
Binary files /dev/null and b/themes/3-material_design/icons/volume.png differ
diff --git a/themes/3-material_design/material_design.th b/themes/3-material_design/material_design.th
new file mode 100644
index 0000000..e5b9d6e
--- /dev/null
+++ b/themes/3-material_design/material_design.th
@@ -0,0 +1,410 @@
+/*****************************************************************************
+MainWindow
+*****************************************************************************/
+QWidget:window {
+ border: 0px solid #2e2f34;
+ background-color: #2e2f34;
+}
+
+/*****************************************************************************
+Search bar
+*****************************************************************************/
+QLineEdit {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-bottom: 2px solid #669900;
+ color: #669900;
+}
+
+/*****************************************************************************
+Scroll Bars
+*****************************************************************************/
+QScrollBar:horizontal {
+ background: transparent; /* Background where slider is not */
+ height: 10px;
+ margin: 0;
+}
+
+QScrollBar:vertical {
+ background: transparent; /* Background where slider is not */
+ width: 10px;
+ margin: 0;
+}
+
+QScrollBar::handle:horizontal {
+ background: #37474F; /* Slider color */
+ min-width: 16px;
+ border-radius: 5px;
+}
+
+QScrollBar::handle:vertical {
+ background: #37474F; /* Slider color */
+ min-height: 16px;
+ border-radius: 5px;
+}
+
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal,
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
+ background: none; /* Removes the dotted background */
+}
+
+QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
+QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { /* Hides the slider arrows */
+ border: none;
+ background: none;
+}
+
+/*****************************************************************************
+List
+*****************************************************************************/
+QListWidget {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-bottom: 2px solid #80CBC4;
+ color: #c2cfd6;
+}
+
+QListView::item:hover {
+ color: #669900;
+ background: transparent;
+}
+
+QListView::item:selected {
+ color: #88cc00;
+ background: transparent;
+}
+
+QListView {
+ background-color: transparent;
+ color: #c2cfd6;
+ outline: 0;
+ border: 0px solid transparent;
+}
+
+/* === QTabBar === */
+QTabBar {
+ background: transparent;
+}
+
+QTabWidget::pane {
+ background: transparent; /* Only at the very bottom of the tabs */
+}
+
+QTabBar::tab {
+ background: transparent;
+ border: 0px solid transparent;
+ border-bottom: 2px solid transparent;
+ color: #546E7A;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+QTabBar::tab:hover {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-bottom: 2px solid #88cc00;
+ color: #AFBDC4;
+}
+
+QTabBar::tab:selected {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-top: none;
+ border-bottom: 2px solid #88cc00;
+ color: #FFFFFF;
+}
+
+QStackedWidget {
+ background: #2e2f34;/* This covers a bunch of things, I was thinking about making it transparent, */
+ /* but I would have to find all the other elements... but QTabWidget::pane may be it */
+}
+
+/* ==================== Dialog ==================== */
+QLabel {
+ background: transparent;
+ color: #CFD8DC; /* Not sure about this one */
+}
+
+QDialog {
+ background-color: #263238;
+ color: #546E7A;
+ outline: 0;
+ border: 2px solid transparent;
+}
+
+/*****************************************************************************
+Buttons
+*****************************************************************************/
+
+QToolTip {
+ background-color: #80CBC4;
+ color: black;
+ padding: 5px;
+ border-radius: 0;
+ opacity: 200;
+}
+
+QPushButton {
+ background-color: transparent;
+ color: #c2cfd6;
+ border: 1px solid transparent;
+ padding: 4px 22px;
+}
+
+QPushButton:hover {
+ border-left: 2px solid #88cc00;
+ border-right: 2px solid #88cc00;
+ color: #f0f3f5;
+}
+
+QPushButton:pressed {
+ color: #efffcc;
+}
+
+QPushButton:disabled {
+ color:#546E7A;
+}
+
+QPushButton:checked {
+ color: #88cc00;
+}
+
+/*****************************************************************************
+Rich Text Box
+*****************************************************************************/
+QTextBrowser {
+ background: transparent;
+ border: 0px solid transparent;
+ color: #546E7A;
+}
+
+/*****************************************************************************
+Main Menu (Upper part)
+*****************************************************************************/
+QTreeView {
+ background-color: #263238;
+}
+
+QMenu {
+ background-color: #263238; /* File Menu Background color */
+ color: #546E7A;
+}
+
+QMenu::item:selected {
+ color: #AFBDC4;
+}
+
+QMenu::item:pressed {
+ color: #FFFFFF;
+}
+
+QMenu::separator {
+ height: 1px;
+ background: transparent; /* Could change this to #546E7A and reduce the margin top and bottom to 1px */
+ margin-left: 10px;
+ margin-right: 10px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+/*****************************************************************************
+Main Menu (Bar)
+*****************************************************************************/
+QMenuBar {
+ background-color: transparent;
+ color: #546E7A;
+}
+
+QMenuBar::item {
+ background: transparent;
+}
+
+QMenuBar::item:disabled {
+ color: gray;
+}
+
+QMenuBar::item:selected {
+ color: #AFBDC4;
+}
+
+QMenuBar::item:pressed {
+ color: #FFFFFF;
+}
+
+QToolBar {
+ background: transparent;
+ border: 1px solid transparent;
+}
+
+QToolBar:handle {
+ background: transparent;
+ border-left: 2px dotted #80CBC4; /* Fix the 4 handle dots so it doesn't look crappy */
+ color: transparent;
+}
+
+QToolBar::separator {
+ border: 0;
+}
+
+/*****************************************************************************
+ComboBox
+*****************************************************************************/
+QComboBox {
+ border: 0px solid gray;
+ border-radius: 2px;
+ padding: 1px 6px 1px 6px;
+ min-width: 2em;
+}
+
+QComboBox:!editable, QComboBox::drop-down:editable {
+ color: #c2cfd6;
+ selection-color: #80CBC4;
+ background-color: transparent;
+ selection-background-color: transparent;
+}
+
+QComboBox:disabled {
+ color: #546E7A;
+}
+
+/* QComboBox gets the "on" state when the popup is open */
+QComboBox:!editable:on,
+QComboBox::drop-down:editable:on {
+ color: #c2cfd6;
+ background-color: transparent;
+ selection-background-color: transparent;
+}
+
+QComboBox:on { /* shift the text when the popup opens */
+ padding-top: 3px;
+ padding-left: 4px;
+}
+
+QComboBox::drop-down {
+ background-color: transparent;
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ width: 20px;
+ border-top-right-radius: 2px;
+ border-bottom-right-radius: 2px;
+}
+
+QComboBox::down-arrow:enabled {
+ image: url("./themes/3-material_design/icons/down-arrow.png");
+}
+
+QComboBox::down-arrow:disabled {
+ image: url("./themes/3-material_design/icons/down-arrow_off.png");
+}
+
+QComboBox::down-arrow:hover {
+ image: url("./themes/3-material_design/icons/down-arrow_hover.png");
+}
+
+QComboBox::down-arrow:on { /* shift the arrow when popup is open */
+ top: 1px;
+ left: 1px;
+}
+
+QComboBox QAbstractItemView {
+background-color: #2e2f34;
+}
+
+/*****************************************************************************
+RadioButton
+*****************************************************************************/
+
+QRadioButton{
+ color: #c2cfd6;
+}
+
+QRadioButton:disabled{
+ color: #546E7A;
+}
+
+QRadioButton::indicator{
+ width: 50px;
+ height: 50px;
+}
+
+QRadioButton::indicator::unchecked {
+ image: url("./themes/3-material_design/icons/off.png");
+}
+
+QRadioButton::indicator:unchecked:hover {
+ image: url("./themes/3-material_design/icons/off_press.png");
+}
+
+QRadioButton::indicator:unchecked:pressed {
+ image: url("./themes/3-material_design/icons/off_press.png");
+}
+
+QRadioButton::indicator::checked {
+ image: url("./themes/3-material_design/icons/on.png");
+}
+
+QRadioButton::indicator:checked:hover {
+ image: url("./themes/3-material_design/icons/on_press.png");
+}
+
+QRadioButton::indicator:checked:pressed {
+ image: url("./themes/3-material_design/icons/on_press.png");
+}
+
+/*****************************************************************************
+SpinBox
+*****************************************************************************/
+QSpinBox {
+ color: #c2cfd6;
+ border-width: 0px;
+ background: transparent;
+}
+
+QSpinBox:disabled {
+ color: #546E7A;
+ border-width: 0px;
+ background: transparent;
+}
+
+QSpinBox::up-button {
+ subcontrol-origin: border;
+ subcontrol-position: top right;
+ width: 16px;
+ image: url("./themes/3-material_design/icons/up-arrow.png");
+ border-width: 0px;
+}
+
+QSpinBox::up-button:hover {
+ image: url("./themes/3-material_design/icons/up-arrow_hover.png");
+}
+
+QSpinBox::up-button:pressed {
+ image: url("./themes/3-material_design/icons/up-arrow.png");
+}
+
+QSpinBox::up-button:disabled {
+ image: url("./themes/3-material_design/icons/up-arrow_off.png");
+}
+
+QSpinBox::down-button {
+ subcontrol-origin: border;
+ subcontrol-position: bottom right; /* position at bottom right corner */
+ width: 16px;
+ image: url("./themes/3-material_design/icons/down-arrow.png");
+ border-width: 0px;
+ border-top-width: 0;
+}
+
+QSpinBox::down-button:hover {
+ image: url("./themes/3-material_design/icons/down-arrow_hover.png");
+}
+
+QSpinBox::down-button:pressed {
+ image: url("./themes/3-material_design/icons/down-arrow.png");
+}
+
+QSpinBox::down-button:disabled {
+ image: url("./themes/3-material_design/icons/down-arrow_off.png");
+}
\ No newline at end of file
diff --git a/utilities.py b/utilities.py
index 9e1453a..3f58e4d 100644
--- a/utilities.py
+++ b/utilities.py
@@ -1,37 +1,70 @@
from collections import namedtuple
import hashlib
+import re
from pandas import read_csv
-class _ReadOnlyProperty(object):
- def __init__(self, value):
- self.__value = value
+from PyQt5.QtWidgets import QMessageBox
+
+# class _ReadOnlyProperty(object):
+# def __init__(self, value):
+# self.__value = value
- def __get__(self, obj, objtype):
- return self.__value
+# def __get__(self, obj, objtype):
+# return self.__value
- def __set__(self, obj, value):
- return NotImplementedError("Cannot change a constant.")
+# def __set__(self, obj, value):
+# return NotImplementedError("Cannot change a constant.")
- # def change_hardcoded_value(self, value):
- # self.__value = value
+# def __make_read_only(cls):
+# for k, v in cls.__dict__.items():
+# if not callable(getattr(cls, k)) and '__' not in k:
+# setattr(cls, k, _ReadOnlyProperty(v))
+# # def raise_err(self, attr, value):
+# # raise NotImplementedError("Cannot add an attribute.")
+# # setattr(cls, '__setattr__', raise_err)
+# return cls
-def __make_read_only(cls):
- for k, v in cls.__dict__.items():
- if not callable(getattr(cls, k)) and '__' not in k:
- setattr(cls, k, _ReadOnlyProperty(v))
- # def raise_err(self, attr, value):
- # raise NotImplementedError("Cannot add an attribute.")
- # setattr(cls, '__setattr__', raise_err)
- return cls
-
-@__make_read_only
-class __Constants(object):
+# @__make_read_only
+class Constants(object):
+ class Messages(object):
+ NO_DB_AVAIL = "No database available.\nGo to Updates->Update database."
+ NO_DB = "No database"
DB_LOCATION = "https://aresvalley.com/Storage/Artemis/Database/data.zip"
REF_LOC = "https://aresvalley.com/Storage/Artemis/Database/data.zip.log"
+ DB_NAME = "db.csv"
+ DB_NAMES = ("name",
+ "inf_freq",
+ "sup_freq",
+ "mode",
+ "inf_band",
+ "sup_band",
+ "location",
+ "url",
+ "description",
+ "modulation",
+ "category_code",
+ "acf",)
+ DB_WIKI_CLICKED = "url_clicked"
+ DB_STRINGS = ('inf_freq',
+ 'sup_freq',
+ 'mode',
+ 'inf_band',
+ 'sup_band',
+ 'category_code',)
DATA_FOLDER = "Data"
SPECTRA_FOLDER = "Spectra"
+ SPECTRA_EXT = ".png"
AUDIO_FOLDER = "Audio"
- ICONS_FOLDER = "icons_imgs"
+ THEMES_FOLDER = "themes"
+ THEME_EXTENSION = ".th"
+ ICONS_FOLDER = "icons"
+ DEFAULT_THEME = "1-system"
+ CURRENT_THEME = ".current_theme"
+ THEME_COLORS = "colors.txt"
+ NOT_AVAILABLE = "spectrumnotavailable.png"
+ NOT_SELECTED = "nosignalselected.png"
+ SEARCH_LABEL_IMG = "search_icon.png"
+ VOLUME_LABEL_IMG = "volume.png"
__Band = namedtuple("Band", ["lower", "upper"])
__ELF = __Band(0, 30) # Formally it is (3, 30) Hz.
__SLF = __Band(30, 300)
@@ -88,7 +121,6 @@ class __Constants(object):
"PSK",
"QAM",
"TDMA",)
-
LOCATIONS = (UNKNOWN,
"Australia",
"Canada",
@@ -121,13 +153,21 @@ class __Constants(object):
"World Wide",
"Worldwide",)
-Constants = __Constants()
+# Constants = __Constants()
def reset_apply_remove_btn(button):
if button.isChecked():
button.setChecked(False)
button.clicked.emit()
+def throwable_message(cls, title, text, connection = None):
+ msg = QMessageBox(cls)
+ msg.setWindowTitle(title)
+ msg.setText(text)
+ if connection:
+ msg.setText(text).finished.connect(connection)
+ return msg
+
def checksum_ok(data, what):
code = hashlib.sha256()
code.update(data)
@@ -141,4 +181,7 @@ def checksum_ok(data, what):
reference = read_csv(Constants.REF_LOC, delimiter = '*').iat[-1, n]
except HTTPError:
return False
- return code.hexdigest() == reference
\ No newline at end of file
+ return code.hexdigest() == reference
+
+def is_valid_html_color(color):
+ return bool(re.match("#([a-zA-Z0-9]){6}", color))