Source code for jdxi_editor.ui.dialogs.settings

"""
Preferences Dialog

Sets settings for various biotoolkit features
"""

import logging

import qtawesome as qta
from decologr import Decologr as log
from PySide6 import QtCore, QtWidgets
from PySide6.QtCore import QSettings, QSize
from PySide6.QtWidgets import (
    QCheckBox,
    QComboBox,
    QDialog,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

from jdxi_editor.project import (
    __organization_name__,
    __package_name__,
    __program__,
    __project__,
    __version__,
)


[docs] def log_settings() -> None: settings = QSettings(__organization_name__, __program__) print(f'log_level {settings.value("log_level", logging.DEBUG, type=int)}') print(f'logging {settings.value("logging", True, type=bool)}')
[docs] class UiPreferencesDialog(QDialog): def __init__(self, parent): super().__init__(parent)
[docs] self.icon_size = None
[docs] self.settings = QSettings(__organization_name__, __program__)
[docs] def ui_setup(self, parent: QWidget = None): """ ui_setup :param parent: QWidget :return: None """ self.icon_size = QSize(40, 40) """if darkdetect.isLight(): theme = "light" else: theme = "dark""" log_settings() self.resize(508, 300) self.setWindowTitle("JD-XI Editor settings") main_layout = QVBoxLayout(self) # Create a QComboBox self.log_level_combo = QComboBox() self.log_levels = { "DEBUG": logging.DEBUG, "INFO": logging.INFO, "WARNING": logging.WARNING, "ERROR": logging.ERROR, "CRITICAL": logging.CRITICAL, } self.log_level_combo.addItems(self.log_levels.keys()) # Load the log level from QSettings # self.load_log_level_from_settings() log_level = int(self.settings.value("log_level", logging.DEBUG)) # Reverse lookup: find the key name for the numeric value try: level_name = next((k for k, v in self.log_levels.items() if v == log_level)) except StopIteration: level_name = "DEBUG" # default index = list(self.log_levels.keys()).index(level_name) if index >= 0: self.log_level_combo.setCurrentIndex(index) # Connect the combo box to a function that updates QSettings self.log_level_combo.currentIndexChanged.connect(self.update_log_level) self.log_level_layout = QHBoxLayout(self) self.log_icon = QLabel() self.log_icon.setPixmap(qta.icon("msc.report").pixmap(self.icon_size)) self.log_level_label = QLabel("Log file error reporting level:") self.log_level_layout.addWidget(self.log_icon) self.log_level_layout.addWidget(self.log_level_label) self.log_level_layout.addWidget(self.log_level_combo) self.logging_layout = QHBoxLayout(self) self.logging_icon = QLabel() self.logging_checkbox = QCheckBox("Enable Logging?") self.logging_checkbox.setLayoutDirection(QtCore.Qt.RightToLeft) self.logging_checkbox.setChecked( bool(self.settings.value("logging", type=bool)) ) self.logging_icon.setPixmap(qta.icon("msc.report").pixmap(self.icon_size)) self.logging_label = QLabel("Logging On or Off:") self.logging_layout.addWidget(self.logging_icon) self.logging_layout.addWidget(self.logging_label) self.logging_layout.addWidget(self.logging_checkbox) self.buttonBox = QtWidgets.QDialogButtonBox(self) self.buttonBox.setGeometry(QtCore.QRect(150, 250, 341, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons( QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok ) self.buttonBox.setObjectName("buttonBox") self.buttonBox.rejected.connect(self.close) self.buttonBox.accepted.connect(self.on_save_settings) self.buttonBox.accepted.connect(self.close) QtCore.QMetaObject.connectSlotsByName(self) main_widget = QWidget() main_layout.addWidget(main_widget) main_content_layout = QVBoxLayout() main_content_layout.addLayout(self.log_level_layout) main_content_layout.addLayout(self.logging_layout) main_widget.setLayout(main_content_layout) main_layout.addWidget(self.buttonBox) self.setLayout(main_layout)
[docs] def load_log_level_from_settings(self): """ Load and migrate log level from settings (handles legacy string values). """ value = self.settings.value("log_level", logging.DEBUG) # Case 1: Value already an integer (new style) if isinstance(value, int): log_level = value # Case 2: Legacy value stored as string (e.g., "CRITICAL") elif isinstance(value, str): # Try to parse as integer first try: log_level = int(value) except ValueError: # Convert known string names log_level = self.log_levels.get(value.upper(), logging.DEBUG) # Migrate: store the numeric version back self.settings.setValue("log_level", log_level) else: # Fallback log_level = logging.DEBUG # Set combo box to correct index level_name = next( (k for k, v in self.log_levels.items() if v == log_level), "DEBUG" ) index = list(self.log_levels.keys()).index(level_name) self.log_level_combo.setCurrentIndex(index) # Set the logger level immediately logging.getLogger(__package_name__).setLevel(log_level)
[docs] def update_log_level(self, level): """ Update log level for the current logger and all handlers """ log.parameter("level", level) logger = logging.getLogger(__package_name__) logger.setLevel(level) for handler in logger.handlers: handler.setLevel(level) # Also apply to root logger and its handlers (optional, if you use root logging) logging.root.setLevel(level) for handler in logging.root.handlers: handler.setLevel(level) self.settings.setValue("log_level", level) self.settings.sync() print(f"✅ Updated log level to {logging.getLevelName(level)}")
[docs] def on_save_settings(self): """ on_save_settings :return: None """ settings = self.settings try: settings.setValue("logging", bool(self.logging_checkbox.isChecked())) settings.sync() log_settings() except Exception as ex: print(f"Error {ex} occurred saving settings")