diff --git a/constants.py b/constants.py index c2a7afe..2904393 100644 --- a/constants.py +++ b/constants.py @@ -14,14 +14,18 @@ class ChecksumWhat(Enum): DB = auto() class Messages(object): - NO_DB_AVAIL = "No database available.\nGo to Updates->Update database." - NO_DB = "No database" - NO_CONNECTION = "No internet connection" - NO_CONNECTION_MSG = "Unable to establish an internet connection." - BAD_DOWNLOAD = "Something went wrong" - BAD_DOWNLOAD_MSG = "Something went wrong with the downaload.\nCheck your internet connection and try again." - BAD_FILE = "Bad file detected" - BAD_FILE_MSG = "The downloaded file seems to be corrupted.\nThe old database has not been deleted and\nthe downloaded file has been discarded." + DB_UP_TO_DATE = "Already up to date" + DB_UP_TO_DATE_MSG = "No newer version to download." + DB_NEW_VER = "New version available" + DB_NEW_VER_MSG = "A new version of the database is available for download." + NO_DB_AVAIL = "No database detected." + NO_DB = "No database" + DOWNLOAD_NOW_QUESTION = "Do you want to download it now?" + DOWNLOAD_ANYWAY_QUESTION = "Do you want to download it anyway?" + NO_CONNECTION = "No internet connection" + NO_CONNECTION_MSG = "Unable to establish an internet connection." + BAD_DOWNLOAD = "Something went wrong" + BAD_DOWNLOAD_MSG = "Something went wrong with the downaload.\nCheck your internet connection and try again." class Signal(object): NAME = "name" diff --git a/download_window.py b/download_window.py index cfce206..8d8d0f0 100644 --- a/download_window.py +++ b/download_window.py @@ -28,11 +28,6 @@ class DownloadWindow(QWidget, Ui_Download_window): text = Messages.BAD_DOWNLOAD_MSG, connection = self.close) - # Never used (should exploit the checksum check for the single file) - self.bad_file_msg = throwable_message(self, title = Messages.BAD_FILE, - text = Messages.BAD_FILE_MSG, - connection = self.close) - self.download_thread = DownloadThread() self.download_thread.finished.connect(self.wait_close) @@ -46,10 +41,6 @@ class DownloadWindow(QWidget, Ui_Download_window): self.bad_db_download_msg.show() self.everything_ok = False - def show_bad_file_warning(self): - self.bad_file_msg.show() - self.everything_ok = False - @pyqtSlot() def terminate_process(self): if self.download_thread.isRunning(): diff --git a/main.py b/main.py index 121aeaf..bb385cf 100644 --- a/main.py +++ b/main.py @@ -12,6 +12,7 @@ from PyQt5.QtWidgets import (QMainWindow, qApp, QDesktopWidget, QListWidgetItem, + QMessageBox, QSplashScreen, QTreeView, QTreeWidgetItem,) @@ -29,7 +30,8 @@ from download_window import DownloadWindow import constants from themes import Theme -from utilities import (uncheck_and_emit, +from utilities import (checksum_ok, + uncheck_and_emit, throwable_message, connect_to, filters_ok, @@ -49,7 +51,8 @@ class MyApp(QMainWindow, Ui_MainWindow): self.set_initial_size() self.download_window = DownloadWindow() self.actionExit.triggered.connect(qApp.quit) - self.action_update_database.triggered.connect(self.download_db) + self.action_update_database.triggered.connect(self.ask_if_download) + self.action_check_db_ver.triggered.connect(self.check_db_ver) self.db = None self.current_signal_name = '' self.signal_names = [] @@ -334,14 +337,13 @@ class MyApp(QMainWindow, Ui_MainWindow): # ########################################################################################## - self.load_db() + # self.load_db() # Left list widget and search bar. 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.display_signals() + 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, @@ -365,8 +367,10 @@ class MyApp(QMainWindow, Ui_MainWindow): BandLabel(self.ehf_left, self.ehf, self.ehf_right), ] +# Final operations. self.theme.initialize() - + self.load_db() + self.display_signals() self.show() @pyqtSlot() @@ -456,6 +460,9 @@ class MyApp(QMainWindow, Ui_MainWindow): self.lower_band_confidence.setFixedWidth(120) self.upper_band_confidence.setFixedWidth(120) + self.freq_gfd.setFixedWidth(200) + self.unit_freq_gfd.setFixedWidth(120) + self.audio_progress.setFixedHeight(20) self.volume.setStyleSheet(""" QSlider::groove:horizontal { @@ -475,9 +482,57 @@ class MyApp(QMainWindow, Ui_MainWindow): @pyqtSlot() def download_db(self): - self.download_window.download_thread.finished.connect(self.show_downloaded_signals) - self.download_window.download_thread.start() - self.download_window.show() + 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() + + @pyqtSlot() + def ask_if_download(self): + if not self.download_window.isVisible(): + db_path = os.path.join(constants.DATA_FOLDER, constants.Database.NAME) + try: + with open(db_path, "rb") as file_db: + db = file_db.read() + except: + self.download_db() + else: + if not checksum_ok(db, constants.ChecksumWhat.DB): + self.download_db() + else: + answer = throwable_message(self, title = constants.Messages.DB_UP_TO_DATE, + text = constants.Messages.DB_UP_TO_DATE_MSG, + informative_text = constants.Messages.DOWNLOAD_ANYWAY_QUESTION, + is_question = True, + default_btn = QMessageBox.No).exec() + if answer == QMessageBox.Yes: + self.download_db() + + @pyqtSlot() + def check_db_ver(self): + if not self.download_window.isVisible(): + db_path = os.path.join(constants.DATA_FOLDER, constants.Database.NAME) + answer = None + try: + with open(db_path, "rb") as file_db: + db = file_db.read() + except: + answer = throwable_message(self, title = constants.Messages.NO_DB, + text = constants.Messages.NO_DB_AVAIL, + informative_text = constants.Messages.DOWNLOAD_NOW_QUESTION, + is_question = True).exec() + else: + if checksum_ok(db, constants.ChecksumWhat.DB): + throwable_message(self, title = constants.Messages.DB_UP_TO_DATE, + text = constants.Messages.DB_UP_TO_DATE_MSG).show() + + else: + answer = throwable_message(self, title = constants.Messages.DB_NEW_VER, + text = constants.Messages.DB_NEW_VER_MSG, + informative_text = constants.Messages.DOWNLOAD_NOW_QUESTION, + is_question = True).exec() + if answer == QMessageBox.Yes: + self.download_db() @pyqtSlot() def show_downloaded_signals(self): @@ -497,14 +552,19 @@ class MyApp(QMainWindow, Ui_MainWindow): names = names,) except FileNotFoundError: self.search_bar.setDisabled(True) - throwable_message(self, title = constants.Messages.NO_DB, - text = constants.Messages.NO_DB_AVAIL).show() + answer = throwable_message(self, title = constants.Messages.NO_DB, + text = constants.Messages.NO_DB_AVAIL, + informative_text = constants.Messages.DOWNLOAD_NOW_QUESTION, + is_question = True).exec() + if answer == QMessageBox.Yes: + self.download_db() else: self.signal_names = self.db.index self.total_signals = len(self.signal_names) self.db.fillna(constants.UNKNOWN, inplace = True) self.db[constants.Signal.WIKI_CLICKED] = False self.update_status_tip(self.total_signals) + self.result_list.addItems(self.signal_names) @pyqtSlot() def set_min_value_upper_limit(self, lower_combo_box, @@ -621,6 +681,8 @@ class MyApp(QMainWindow, Ui_MainWindow): available_signals += 1 else: self.result_list.item(index).setHidden(True) + # Remove selected item. + self.result_list.selectionModel().clear() self.update_status_tip(available_signals) def update_status_tip(self, available_signals): @@ -959,12 +1021,12 @@ class MyApp(QMainWindow, Ui_MainWindow): if __name__ == '__main__': my_app = QApplication(sys.argv) - img = QPixmap("splash.jpg") - img = img.scaled(600, 600, aspectRatioMode = Qt.KeepAspectRatio) - splash = QSplashScreen(img) - splash.show() - splash.showMessage("Loading database...") - sleep(2) + # img = QPixmap("splash.jpg") + # img = img.scaled(600, 600, aspectRatioMode = Qt.KeepAspectRatio) + # splash = QSplashScreen(img) + # splash.show() + # splash.showMessage("Loading database...") + # sleep(2) w = MyApp() - splash.finish(w) + # splash.finish(w) sys.exit(my_app.exec_()) diff --git a/main_window.ui b/main_window.ui index 6fc624e..2fd0733 100644 --- a/main_window.ui +++ b/main_window.ui @@ -178,7 +178,7 @@ QTabWidget::Rounded - 2 + 0 true @@ -1775,7 +1775,7 @@ p, li { white-space: pre-wrap; } - 4 + 0 true @@ -4869,6 +4869,7 @@ QSlider::handle:horizontal { Updates + @@ -4895,6 +4896,11 @@ QSlider::handle:horizontal { Update database + + + Check latest database version + + diff --git a/themes/3-material_design/colors.txt b/themes/3-material_design/colors.txt deleted file mode 100644 index cd95572..0000000 --- a/themes/3-material_design/colors.txt +++ /dev/null @@ -1,2 +0,0 @@ -active=#ddffdf -inactive=#949494 \ No newline at end of file diff --git a/themes/3-material_design/icons/down-arrow.png b/themes/3-material_design/icons/down-arrow.png deleted file mode 100644 index b2cd4a5..0000000 Binary files a/themes/3-material_design/icons/down-arrow.png and /dev/null differ diff --git a/themes/3-material_design/icons/down-arrow_hover.png b/themes/3-material_design/icons/down-arrow_hover.png deleted file mode 100644 index f7ad171..0000000 Binary files a/themes/3-material_design/icons/down-arrow_hover.png and /dev/null differ diff --git a/themes/3-material_design/icons/down-arrow_off.png b/themes/3-material_design/icons/down-arrow_off.png deleted file mode 100644 index e7f0af3..0000000 Binary files a/themes/3-material_design/icons/down-arrow_off.png and /dev/null differ diff --git a/themes/3-material_design/icons/off.png b/themes/3-material_design/icons/off.png deleted file mode 100644 index ef39d9e..0000000 Binary files a/themes/3-material_design/icons/off.png and /dev/null differ diff --git a/themes/3-material_design/icons/off_press.png b/themes/3-material_design/icons/off_press.png deleted file mode 100644 index 3355d12..0000000 Binary files a/themes/3-material_design/icons/off_press.png and /dev/null differ diff --git a/themes/3-material_design/icons/on.png b/themes/3-material_design/icons/on.png deleted file mode 100644 index 2244ffe..0000000 Binary files a/themes/3-material_design/icons/on.png and /dev/null differ diff --git a/themes/3-material_design/icons/on_press.png b/themes/3-material_design/icons/on_press.png deleted file mode 100644 index 4754508..0000000 Binary files a/themes/3-material_design/icons/on_press.png and /dev/null differ diff --git a/themes/3-material_design/icons/search_icon.png b/themes/3-material_design/icons/search_icon.png deleted file mode 100644 index dd0ec52..0000000 Binary files a/themes/3-material_design/icons/search_icon.png and /dev/null differ diff --git a/themes/3-material_design/icons/up-arrow.png b/themes/3-material_design/icons/up-arrow.png deleted file mode 100644 index 6f0f090..0000000 Binary files a/themes/3-material_design/icons/up-arrow.png and /dev/null differ diff --git a/themes/3-material_design/icons/up-arrow_hover.png b/themes/3-material_design/icons/up-arrow_hover.png deleted file mode 100644 index 149eae0..0000000 Binary files a/themes/3-material_design/icons/up-arrow_hover.png and /dev/null differ diff --git a/themes/3-material_design/icons/up-arrow_off.png b/themes/3-material_design/icons/up-arrow_off.png deleted file mode 100644 index ac2217f..0000000 Binary files a/themes/3-material_design/icons/up-arrow_off.png and /dev/null differ diff --git a/themes/3-material_design/icons/volume.png b/themes/3-material_design/icons/volume.png deleted file mode 100644 index 88e4c7e..0000000 Binary files a/themes/3-material_design/icons/volume.png and /dev/null differ diff --git a/themes/3-material_design/material_design.qss b/themes/3-material_design/material_design.qss deleted file mode 100644 index e5b9d6e..0000000 --- a/themes/3-material_design/material_design.qss +++ /dev/null @@ -1,410 +0,0 @@ -/***************************************************************************** -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 2855341..6be34e7 100644 --- a/utilities.py +++ b/utilities.py @@ -13,12 +13,22 @@ def uncheck_and_emit(button): button.setChecked(False) button.clicked.emit() -def throwable_message(cls, title, text, connection = None): +def throwable_message(cls, title, text, + informative_text = None, + connection = None, + is_question = False, + default_btn = QMessageBox.Yes): msg = QMessageBox(cls) msg.setWindowTitle(title) msg.setText(text) + if informative_text: + msg.setInformativeText(informative_text) if connection: msg.finished.connect(connection) + if is_question: + msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) + msg.setDefaultButton(default_btn) + msg.adjustSize() return msg def checksum_ok(data, what): @@ -26,7 +36,7 @@ def checksum_ok(data, what): code.update(data) if what == constants.ChecksumWhat.FOLDER: n = 0 - elif what == constants.ChecksumWhat.DB: # This is for a runtime check of db version and suggest an update.. + elif what == constants.ChecksumWhat.DB: n = 1 else: raise ValueError("Wrong entry name.")