From db7f9b85795e409a264029e28e15fea55cd1d338 Mon Sep 17 00:00:00 2001 From: Kien Le <kienle@passcal.nmt.edu> Date: Fri, 21 Apr 2023 14:12:44 -0600 Subject: [PATCH] Save read options to config file --- .gitignore | 3 + sohstationviewer/view/main_window.py | 43 +++++++- sohstationviewer/view/ui/main_ui.py | 144 +++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2baa0937c..e8dc4f63e 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,6 @@ ENV/ .idea/ .DS_Store + +# program config +sohstationviewer/conf/read_settings.ini diff --git a/sohstationviewer/view/main_window.py b/sohstationviewer/view/main_window.py index e55b13a24..6f587cd57 100755 --- a/sohstationviewer/view/main_window.py +++ b/sohstationviewer/view/main_window.py @@ -182,7 +182,9 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): self.is_plotting_tps: bool = False self.is_stopping: bool = False - self.background_black_radio_button.toggle() + self.read_config() + self.validate_config() + self.apply_config() @QtCore.Slot() def open_data_type(self) -> None: @@ -953,6 +955,45 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): for window in QtWidgets.QApplication.topLevelWidgets(): window.close() + self.write_config() + + def write_config(self): + """ + Write the current state of the program to the config file. + """ + self.config.set('FileRead', 'from_data_card', + str(self.from_data_card_check_box.isChecked())) + self.config.set('FileRead', 'data', + str(self.data_radio_button.isChecked())) + self.config.set('FileRead', 'sdata', + str(self.sdata_radio_button.isChecked())) + self.config.set('ColorMode', 'black', + str(self.background_black_radio_button.isChecked())) + self.config.set('ColorMode', 'white', + str(self.background_white_radio_button.isChecked())) + self.config.set('Gap', 'min_gap_length', + self.gap_len_line_edit.text()) + self.config.set('Channels', 'mp123zne', + str(self.mass_pos_123zne_check_box.isChecked())) + self.config.set('Channels', 'mp456uvw', + str(self.mass_pos_456uvw_check_box.isChecked())) + self.config.set('Channels', 'all_waveform_chans', + str(self.all_wf_chans_check_box.isChecked())) + for i, checkbox in enumerate(self.ds_check_boxes, start=1): + self.config.set('Channels', f'ds{i}', str(checkbox.isChecked())) + self.config.set('Channels', 'mseed_wildcard', + self.mseed_wildcard_edit.text()) + self.config.set('Channels', 'plot_tps', + str(self.tps_check_box.isChecked())) + self.config.set('Channels', 'plot_raw', + str(self.raw_check_box.isChecked())) + self.config.set('ChannelsPreference', 'all_soh', + str(self.all_soh_chans_check_box.isChecked())) + self.config.set('ChannelsPreference', 'pref_code', + self.curr_pref_soh_list_name_txtbox.text()) + with open('sohstationviewer/conf/read_settings.ini', 'w') as file: + self.config.write(file) + def delete_old_temp_data_folder(self) -> None: """ Delete temp_data_folder which is used for keeping memmap files in case diff --git a/sohstationviewer/view/ui/main_ui.py b/sohstationviewer/view/ui/main_ui.py index 2fa1d897d..29ea00c64 100755 --- a/sohstationviewer/view/ui/main_ui.py +++ b/sohstationviewer/view/ui/main_ui.py @@ -1,4 +1,6 @@ # UI and connectSignals for main_window +import configparser +from pathlib import Path from typing import Union, List, Optional from PySide2 import QtCore, QtGui, QtWidgets @@ -263,6 +265,8 @@ class UIMainWindow(object): """ self.doc_action: Union[QAction, None] = None + self.config: Union[configparser.ConfigParser, None] = None + def setup_ui(self, main_window): """ Setting up layout, widgets, menus for main_window @@ -451,6 +455,8 @@ class UIMainWindow(object): gap_layout.addWidget(self.gap_len_line_edit) gap_layout.addWidget(QLabel(' m')) + add_separation_line(left_layout) + mass_pos_layout = QHBoxLayout() left_layout.addLayout(mass_pos_layout) mass_pos_layout.addWidget(QLabel('Mass Pos ')) @@ -785,3 +791,141 @@ class UIMainWindow(object): self.read_button.clicked.connect(main_window.read_selected_files) self.stop_button.clicked.connect(main_window.stop) + + def read_config(self): + self.config = configparser.ConfigParser() + config_path = Path('sohstationviewer/conf/read_settings.ini') + if not config_path.exists(): + default_config = ''' + [FileRead] + from_data_card = False + data = False + sdata = False + + [ColorMode] + black = True + white = False + + [Gap] + min_gap_length = + + [Channels] + mp123zne = False + mp456uvw = False + all_waveform_chans = False + ds1 = False + ds2 = False + ds3 = False + ds4 = False + ds5 = False + ds6 = False + ds7 = False + ds8 = False + mseed_wildcard = + plot_tps = False + plot_raw = False + + [ChannelsPreference] + all_soh = True + pref_code = + ''' + self.config.read_string(default_config) + else: + self.config.read(config_path) + + def validate_config(self): + class BadConfigError(RuntimeError): + """ + Error raised when there is a problem with the configuration + """ + pass + + expected_keys = {'from_data_card', 'data', 'sdata', + 'black', 'white', + 'min_gap_length', + 'mp123zne', 'mp456uvw', 'all_waveform_chans', 'ds1', + 'ds2', 'ds3', 'ds4', 'ds5', 'ds6', 'ds7', 'ds8', + # noqa + 'mseed_wildcard', 'plot_tps', 'plot_raw', + 'all_soh', 'pref_code'} + loaded_keys = {item[0] + for (section, _) in self.config.items() + for item in self.config.items(section)} + missing_keys = expected_keys - loaded_keys + if missing_keys: + raise BadConfigError(f'Some required keys are missing. Please' + f'make sure they are in the config file. The ' + f'missing keys are: {", ".join(missing_keys)}' + ) + + data_checked = self.config.getboolean('FileRead', 'data') + sdata_checked = self.config.getboolean('FileRead', 'sdata') + if data_checked and sdata_checked: + raise BadConfigError('data and sdata cannot both be chosen.') + + black_color_mode = self.config.getboolean('ColorMode', 'black') + white_color_mode = self.config.getboolean('ColorMode', 'white') + if black_color_mode and white_color_mode: + raise BadConfigError('Cannot be in both color modes at once.') + + all_waveform_chans = self.config.getboolean('Channels', + 'all_waveform_chans') + data_stream_chosen = any(self.config.getboolean('Channels', f'ds{i}') + for i in range(1, 9) + ) + mseed_wildcard = self.config.get('Channels', + 'mseed_wildcard') + wildcard_not_empty = (mseed_wildcard != '') + if all_waveform_chans and (data_stream_chosen or wildcard_not_empty): + raise BadConfigError( + 'Waveform channel selector can only be in one mode at a time.') + + all_soh = self.config.getboolean('ChannelsPreference', 'all_soh') + channel_pref_code = self.config.get('ChannelsPreference', 'pref_code') + if all_soh and (channel_pref_code != ''): + raise BadConfigError('You can only choose one list of channels to ' + 'be plotted.') + + def apply_config(self): + get_bool = self.config.getboolean + + self.from_data_card_check_box.setChecked( + get_bool('FileRead', 'from_data_card') + ) + self.data_radio_button.setChecked(get_bool('FileRead', 'data')) + self.sdata_radio_button.setChecked(get_bool('FileRead', 'sdata')) + + self.background_black_radio_button.setChecked( + get_bool('ColorMode', 'black') + ) + self.background_white_radio_button.setChecked( + get_bool('ColorMode', 'white') + ) + + self.gap_len_line_edit.setText( + self.config.get('Gap', 'min_gap_length') + ) + + self.mass_pos_123zne_check_box.setChecked( + get_bool('Channels', 'mp123zne') + ) + self.mass_pos_456uvw_check_box.setChecked( + get_bool('Channels', 'mp456uvw') + ) + self.all_wf_chans_check_box.setChecked( + get_bool('Channels', 'all_waveform_chans') + ) + for i, checkbox in enumerate(self.ds_check_boxes, start=1): + checkbox.setChecked(get_bool('Channels', f'ds{i}')) + self.mseed_wildcard_edit.setText( + self.config.get('Channels', 'mseed_wildcard') + ) + self.tps_check_box.setChecked(get_bool('Channels', 'plot_tps')) + self.raw_check_box.setChecked(get_bool('Channels', 'plot_raw')) + + self.all_soh_chans_check_box.setChecked( + get_bool('ChannelsPreference', 'all_soh') + ) + self.curr_pref_soh_list_name_txtbox.setText( + self.config.get('ChannelsPreference', 'pref_code') + ) -- GitLab