635 lines
24 KiB
Python
635 lines
24 KiB
Python
"""
|
|
Settings View - Application configuration and preferences
|
|
Manages all application settings, model configurations, and system preferences.
|
|
"""
|
|
|
|
from PySide6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
|
QGroupBox, QGridLayout, QFrame, QScrollArea, QTabWidget,
|
|
QLineEdit, QSpinBox, QDoubleSpinBox, QComboBox, QCheckBox,
|
|
QSlider, QTextEdit, QFileDialog, QMessageBox, QProgressBar,
|
|
QFormLayout, QButtonGroup, QRadioButton
|
|
)
|
|
from PySide6.QtCore import Qt, Signal, Slot, QTimer, QSettings, QThread
|
|
from PySide6.QtGui import QFont, QPixmap
|
|
|
|
import os
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Import finale components
|
|
from ..styles import FinaleStyles, MaterialColors
|
|
from ..icons import FinaleIcons
|
|
from qt_app_pyside.ui.config_panel import ConfigPanel
|
|
from qt_app_pyside.utils.helpers import load_configuration, save_configuration
|
|
from qt_app_pyside.utils.helpers import format_timestamp, format_duration
|
|
|
|
class ModelConfigWidget(QGroupBox):
|
|
"""
|
|
Widget for configuring AI models and detection parameters.
|
|
"""
|
|
|
|
config_changed = Signal(dict)
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__("AI Model Configuration", parent)
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
"""Setup model configuration UI"""
|
|
layout = QFormLayout(self)
|
|
|
|
# Vehicle detection model
|
|
self.vehicle_model_edit = QLineEdit()
|
|
self.vehicle_model_edit.setPlaceholderText("Path to vehicle detection model...")
|
|
|
|
vehicle_browse_btn = QPushButton(FinaleIcons.get_icon("folder"), "")
|
|
vehicle_browse_btn.setFixedSize(32, 32)
|
|
vehicle_browse_btn.clicked.connect(lambda: self.browse_model("vehicle"))
|
|
|
|
vehicle_layout = QHBoxLayout()
|
|
vehicle_layout.addWidget(self.vehicle_model_edit)
|
|
vehicle_layout.addWidget(vehicle_browse_btn)
|
|
|
|
layout.addRow("Vehicle Model:", vehicle_layout)
|
|
|
|
# Traffic light detection model
|
|
self.traffic_model_edit = QLineEdit()
|
|
self.traffic_model_edit.setPlaceholderText("Path to traffic light model...")
|
|
|
|
traffic_browse_btn = QPushButton(FinaleIcons.get_icon("folder"), "")
|
|
traffic_browse_btn.setFixedSize(32, 32)
|
|
traffic_browse_btn.clicked.connect(lambda: self.browse_model("traffic"))
|
|
|
|
traffic_layout = QHBoxLayout()
|
|
traffic_layout.addWidget(self.traffic_model_edit)
|
|
traffic_layout.addWidget(traffic_browse_btn)
|
|
|
|
layout.addRow("Traffic Light Model:", traffic_layout)
|
|
|
|
# Detection parameters
|
|
self.confidence_spin = QDoubleSpinBox()
|
|
self.confidence_spin.setRange(0.1, 1.0)
|
|
self.confidence_spin.setSingleStep(0.05)
|
|
self.confidence_spin.setValue(0.3)
|
|
self.confidence_spin.setSuffix(" (30%)")
|
|
layout.addRow("Confidence Threshold:", self.confidence_spin)
|
|
|
|
self.nms_spin = QDoubleSpinBox()
|
|
self.nms_spin.setRange(0.1, 1.0)
|
|
self.nms_spin.setSingleStep(0.05)
|
|
self.nms_spin.setValue(0.45)
|
|
layout.addRow("NMS Threshold:", self.nms_spin)
|
|
|
|
self.max_detections_spin = QSpinBox()
|
|
self.max_detections_spin.setRange(10, 1000)
|
|
self.max_detections_spin.setValue(100)
|
|
layout.addRow("Max Detections:", self.max_detections_spin)
|
|
|
|
# Device selection
|
|
self.device_combo = QComboBox()
|
|
self.device_combo.addItems(["CPU", "GPU", "AUTO"])
|
|
layout.addRow("Device:", self.device_combo)
|
|
|
|
# Model optimization
|
|
self.optimize_check = QCheckBox("Enable Model Optimization")
|
|
self.optimize_check.setChecked(True)
|
|
layout.addRow(self.optimize_check)
|
|
|
|
# Apply styling
|
|
self.setStyleSheet(FinaleStyles.get_group_box_style())
|
|
|
|
@Slot()
|
|
def browse_model(self, model_type):
|
|
"""Browse for model file"""
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
self, f"Select {model_type.title()} Model", "",
|
|
"Model Files (*.xml *.onnx *.pt *.bin);;All Files (*)"
|
|
)
|
|
|
|
if file_path:
|
|
if model_type == "vehicle":
|
|
self.vehicle_model_edit.setText(file_path)
|
|
elif model_type == "traffic":
|
|
self.traffic_model_edit.setText(file_path)
|
|
|
|
def get_config(self):
|
|
"""Get current model configuration"""
|
|
return {
|
|
'vehicle_model': self.vehicle_model_edit.text(),
|
|
'traffic_model': self.traffic_model_edit.text(),
|
|
'confidence_threshold': self.confidence_spin.value(),
|
|
'nms_threshold': self.nms_spin.value(),
|
|
'max_detections': self.max_detections_spin.value(),
|
|
'device': self.device_combo.currentText(),
|
|
'optimize_model': self.optimize_check.isChecked()
|
|
}
|
|
|
|
def set_config(self, config):
|
|
"""Set model configuration"""
|
|
self.vehicle_model_edit.setText(config.get('vehicle_model', ''))
|
|
self.traffic_model_edit.setText(config.get('traffic_model', ''))
|
|
self.confidence_spin.setValue(config.get('confidence_threshold', 0.3))
|
|
self.nms_spin.setValue(config.get('nms_threshold', 0.45))
|
|
self.max_detections_spin.setValue(config.get('max_detections', 100))
|
|
self.device_combo.setCurrentText(config.get('device', 'CPU'))
|
|
self.optimize_check.setChecked(config.get('optimize_model', True))
|
|
|
|
class ViolationConfigWidget(QGroupBox):
|
|
"""
|
|
Widget for configuring violation detection parameters.
|
|
"""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__("Violation Detection", parent)
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
"""Setup violation configuration UI"""
|
|
layout = QFormLayout(self)
|
|
|
|
# Red light violation
|
|
self.red_light_check = QCheckBox("Enable Red Light Detection")
|
|
self.red_light_check.setChecked(True)
|
|
layout.addRow(self.red_light_check)
|
|
|
|
self.red_light_sensitivity = QSlider(Qt.Horizontal)
|
|
self.red_light_sensitivity.setRange(1, 10)
|
|
self.red_light_sensitivity.setValue(5)
|
|
layout.addRow("Red Light Sensitivity:", self.red_light_sensitivity)
|
|
|
|
# Speed violation
|
|
self.speed_check = QCheckBox("Enable Speed Detection")
|
|
self.speed_check.setChecked(True)
|
|
layout.addRow(self.speed_check)
|
|
|
|
self.speed_limit_spin = QSpinBox()
|
|
self.speed_limit_spin.setRange(10, 200)
|
|
self.speed_limit_spin.setValue(50)
|
|
self.speed_limit_spin.setSuffix(" km/h")
|
|
layout.addRow("Speed Limit:", self.speed_limit_spin)
|
|
|
|
self.speed_tolerance_spin = QSpinBox()
|
|
self.speed_tolerance_spin.setRange(0, 20)
|
|
self.speed_tolerance_spin.setValue(5)
|
|
self.speed_tolerance_spin.setSuffix(" km/h")
|
|
layout.addRow("Speed Tolerance:", self.speed_tolerance_spin)
|
|
|
|
# Wrong lane detection
|
|
self.wrong_lane_check = QCheckBox("Enable Wrong Lane Detection")
|
|
self.wrong_lane_check.setChecked(True)
|
|
layout.addRow(self.wrong_lane_check)
|
|
|
|
# Helmet detection
|
|
self.helmet_check = QCheckBox("Enable Helmet Detection")
|
|
self.helmet_check.setChecked(False)
|
|
layout.addRow(self.helmet_check)
|
|
|
|
# Violation zone setup
|
|
self.zone_setup_btn = QPushButton(FinaleIcons.get_icon("map"), "Setup Violation Zones")
|
|
layout.addRow(self.zone_setup_btn)
|
|
|
|
# Apply styling
|
|
self.setStyleSheet(FinaleStyles.get_group_box_style())
|
|
|
|
class UIPreferencesWidget(QGroupBox):
|
|
"""
|
|
Widget for UI preferences and appearance settings.
|
|
"""
|
|
|
|
theme_changed = Signal(bool) # dark_mode
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__("User Interface", parent)
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
"""Setup UI preferences"""
|
|
layout = QFormLayout(self)
|
|
|
|
# Theme selection
|
|
theme_group = QButtonGroup(self)
|
|
self.dark_radio = QRadioButton("Dark Theme")
|
|
self.light_radio = QRadioButton("Light Theme")
|
|
self.auto_radio = QRadioButton("Auto (System)")
|
|
|
|
self.dark_radio.setChecked(True) # Default to dark
|
|
|
|
theme_group.addButton(self.dark_radio)
|
|
theme_group.addButton(self.light_radio)
|
|
theme_group.addButton(self.auto_radio)
|
|
|
|
theme_layout = QVBoxLayout()
|
|
theme_layout.addWidget(self.dark_radio)
|
|
theme_layout.addWidget(self.light_radio)
|
|
theme_layout.addWidget(self.auto_radio)
|
|
|
|
layout.addRow("Theme:", theme_layout)
|
|
|
|
# Language selection
|
|
self.language_combo = QComboBox()
|
|
self.language_combo.addItems(["English", "Español", "Français", "Deutsch", "العربية"])
|
|
layout.addRow("Language:", self.language_combo)
|
|
|
|
# Font size
|
|
self.font_size_spin = QSpinBox()
|
|
self.font_size_spin.setRange(8, 16)
|
|
self.font_size_spin.setValue(9)
|
|
layout.addRow("Font Size:", self.font_size_spin)
|
|
|
|
# Animations
|
|
self.animations_check = QCheckBox("Enable Animations")
|
|
self.animations_check.setChecked(True)
|
|
layout.addRow(self.animations_check)
|
|
|
|
# Sound notifications
|
|
self.sound_check = QCheckBox("Sound Notifications")
|
|
self.sound_check.setChecked(True)
|
|
layout.addRow(self.sound_check)
|
|
|
|
# Auto-save
|
|
self.autosave_check = QCheckBox("Auto-save Configuration")
|
|
self.autosave_check.setChecked(True)
|
|
layout.addRow(self.autosave_check)
|
|
|
|
# Update interval
|
|
self.update_interval_spin = QSpinBox()
|
|
self.update_interval_spin.setRange(100, 5000)
|
|
self.update_interval_spin.setValue(1000)
|
|
self.update_interval_spin.setSuffix(" ms")
|
|
layout.addRow("Update Interval:", self.update_interval_spin)
|
|
|
|
# Connect theme signals
|
|
self.dark_radio.toggled.connect(lambda checked: self.theme_changed.emit(True) if checked else None)
|
|
self.light_radio.toggled.connect(lambda checked: self.theme_changed.emit(False) if checked else None)
|
|
|
|
# Apply styling
|
|
self.setStyleSheet(FinaleStyles.get_group_box_style())
|
|
|
|
class PerformanceWidget(QGroupBox):
|
|
"""
|
|
Widget for performance and system settings.
|
|
"""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__("Performance", parent)
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
"""Setup performance settings"""
|
|
layout = QFormLayout(self)
|
|
|
|
# Processing threads
|
|
self.threads_spin = QSpinBox()
|
|
self.threads_spin.setRange(1, 16)
|
|
self.threads_spin.setValue(4)
|
|
layout.addRow("Processing Threads:", self.threads_spin)
|
|
|
|
# Frame buffer size
|
|
self.buffer_size_spin = QSpinBox()
|
|
self.buffer_size_spin.setRange(1, 100)
|
|
self.buffer_size_spin.setValue(10)
|
|
layout.addRow("Frame Buffer Size:", self.buffer_size_spin)
|
|
|
|
# Memory limit
|
|
self.memory_limit_spin = QSpinBox()
|
|
self.memory_limit_spin.setRange(512, 8192)
|
|
self.memory_limit_spin.setValue(2048)
|
|
self.memory_limit_spin.setSuffix(" MB")
|
|
layout.addRow("Memory Limit:", self.memory_limit_spin)
|
|
|
|
# GPU acceleration
|
|
self.gpu_check = QCheckBox("Enable GPU Acceleration")
|
|
self.gpu_check.setChecked(False)
|
|
layout.addRow(self.gpu_check)
|
|
|
|
# Performance mode
|
|
self.performance_combo = QComboBox()
|
|
self.performance_combo.addItems(["Balanced", "Performance", "Power Save"])
|
|
layout.addRow("Performance Mode:", self.performance_combo)
|
|
|
|
# Logging level
|
|
self.logging_combo = QComboBox()
|
|
self.logging_combo.addItems(["DEBUG", "INFO", "WARNING", "ERROR"])
|
|
self.logging_combo.setCurrentText("INFO")
|
|
layout.addRow("Logging Level:", self.logging_combo)
|
|
|
|
# Apply styling
|
|
self.setStyleSheet(FinaleStyles.get_group_box_style())
|
|
|
|
class DataManagementWidget(QGroupBox):
|
|
"""
|
|
Widget for data storage and export settings.
|
|
"""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__("Data Management", parent)
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
"""Setup data management settings"""
|
|
layout = QFormLayout(self)
|
|
|
|
# Data directory
|
|
self.data_dir_edit = QLineEdit()
|
|
self.data_dir_edit.setPlaceholderText("Data storage directory...")
|
|
|
|
data_browse_btn = QPushButton(FinaleIcons.get_icon("folder"), "")
|
|
data_browse_btn.setFixedSize(32, 32)
|
|
data_browse_btn.clicked.connect(self.browse_data_directory)
|
|
|
|
data_layout = QHBoxLayout()
|
|
data_layout.addWidget(self.data_dir_edit)
|
|
data_layout.addWidget(data_browse_btn)
|
|
|
|
layout.addRow("Data Directory:", data_layout)
|
|
|
|
# Auto-export
|
|
self.auto_export_check = QCheckBox("Auto-export Violations")
|
|
layout.addRow(self.auto_export_check)
|
|
|
|
# Export format
|
|
self.export_format_combo = QComboBox()
|
|
self.export_format_combo.addItems(["JSON", "CSV", "XML", "PDF"])
|
|
layout.addRow("Export Format:", self.export_format_combo)
|
|
|
|
# Data retention
|
|
self.retention_spin = QSpinBox()
|
|
self.retention_spin.setRange(1, 365)
|
|
self.retention_spin.setValue(30)
|
|
self.retention_spin.setSuffix(" days")
|
|
layout.addRow("Data Retention:", self.retention_spin)
|
|
|
|
# Backup settings
|
|
self.backup_check = QCheckBox("Enable Automatic Backup")
|
|
layout.addRow(self.backup_check)
|
|
|
|
self.backup_interval_combo = QComboBox()
|
|
self.backup_interval_combo.addItems(["Daily", "Weekly", "Monthly"])
|
|
layout.addRow("Backup Interval:", self.backup_interval_combo)
|
|
|
|
# Database cleanup
|
|
cleanup_btn = QPushButton(FinaleIcons.get_icon("delete"), "Cleanup Old Data")
|
|
layout.addRow(cleanup_btn)
|
|
|
|
# Apply styling
|
|
self.setStyleSheet(FinaleStyles.get_group_box_style())
|
|
|
|
@Slot()
|
|
def browse_data_directory(self):
|
|
"""Browse for data directory"""
|
|
directory = QFileDialog.getExistingDirectory(
|
|
self, "Select Data Directory", self.data_dir_edit.text()
|
|
)
|
|
if directory:
|
|
self.data_dir_edit.setText(directory)
|
|
|
|
class SettingsView(QWidget):
|
|
"""
|
|
Main settings view with tabbed configuration sections.
|
|
"""
|
|
|
|
settings_changed = Signal(dict)
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.config = load_configuration('config.json')
|
|
# Add configuration panel from original
|
|
self.config_panel = ConfigPanel()
|
|
self.settings = QSettings("Finale", "TrafficMonitoring")
|
|
self.setup_ui()
|
|
self.load_settings()
|
|
|
|
def setup_ui(self):
|
|
"""Setup the settings view UI"""
|
|
layout = QVBoxLayout(self)
|
|
layout.setContentsMargins(16, 16, 16, 16)
|
|
layout.setSpacing(16)
|
|
|
|
# Header
|
|
header_layout = QHBoxLayout()
|
|
|
|
title_label = QLabel("Settings")
|
|
title_label.setFont(QFont("Segoe UI", 18, QFont.Bold))
|
|
|
|
# Action buttons
|
|
self.reset_btn = QPushButton(FinaleIcons.get_icon("refresh"), "Reset to Defaults")
|
|
self.reset_btn.clicked.connect(self.reset_to_defaults)
|
|
|
|
self.export_btn = QPushButton(FinaleIcons.get_icon("export"), "Export Settings")
|
|
self.export_btn.clicked.connect(self.export_settings)
|
|
|
|
self.import_btn = QPushButton(FinaleIcons.get_icon("import"), "Import Settings")
|
|
self.import_btn.clicked.connect(self.import_settings)
|
|
|
|
header_layout.addWidget(title_label)
|
|
header_layout.addStretch()
|
|
header_layout.addWidget(self.reset_btn)
|
|
header_layout.addWidget(self.export_btn)
|
|
header_layout.addWidget(self.import_btn)
|
|
|
|
layout.addLayout(header_layout)
|
|
|
|
# Settings tabs
|
|
self.tabs = QTabWidget()
|
|
|
|
# Create configuration widgets
|
|
self.model_config = ModelConfigWidget()
|
|
self.violation_config = ViolationConfigWidget()
|
|
self.ui_preferences = UIPreferencesWidget()
|
|
self.performance_config = PerformanceWidget()
|
|
self.data_management = DataManagementWidget()
|
|
|
|
# Add tabs
|
|
self.tabs.addTab(self.model_config, FinaleIcons.get_icon("model"), "AI Models")
|
|
self.tabs.addTab(self.violation_config, FinaleIcons.get_icon("warning"), "Violations")
|
|
self.tabs.addTab(self.ui_preferences, FinaleIcons.get_icon("palette"), "Interface")
|
|
self.tabs.addTab(self.performance_config, FinaleIcons.get_icon("speed"), "Performance")
|
|
self.tabs.addTab(self.data_management, FinaleIcons.get_icon("database"), "Data")
|
|
|
|
# Style tabs
|
|
self.tabs.setStyleSheet(FinaleStyles.get_tab_widget_style())
|
|
|
|
layout.addWidget(self.tabs, 1)
|
|
|
|
# Bottom action bar
|
|
action_layout = QHBoxLayout()
|
|
|
|
self.apply_btn = QPushButton(FinaleIcons.get_icon("check"), "Apply")
|
|
self.apply_btn.clicked.connect(self.apply_settings)
|
|
|
|
self.save_btn = QPushButton(FinaleIcons.get_icon("save"), "Save")
|
|
self.save_btn.clicked.connect(self.save_settings)
|
|
|
|
self.cancel_btn = QPushButton(FinaleIcons.get_icon("close"), "Cancel")
|
|
self.cancel_btn.clicked.connect(self.cancel_changes)
|
|
|
|
action_layout.addStretch()
|
|
action_layout.addWidget(self.apply_btn)
|
|
action_layout.addWidget(self.save_btn)
|
|
action_layout.addWidget(self.cancel_btn)
|
|
|
|
layout.addLayout(action_layout)
|
|
|
|
# Connect signals
|
|
self.ui_preferences.theme_changed.connect(self.on_theme_changed)
|
|
|
|
# Apply theme
|
|
self.apply_theme(True)
|
|
|
|
def load_settings(self):
|
|
"""Load settings from QSettings"""
|
|
# Load model configuration
|
|
model_config = {
|
|
'vehicle_model': self.settings.value('model/vehicle_model', ''),
|
|
'traffic_model': self.settings.value('model/traffic_model', ''),
|
|
'confidence_threshold': self.settings.value('model/confidence_threshold', 0.3, float),
|
|
'nms_threshold': self.settings.value('model/nms_threshold', 0.45, float),
|
|
'max_detections': self.settings.value('model/max_detections', 100, int),
|
|
'device': self.settings.value('model/device', 'CPU'),
|
|
'optimize_model': self.settings.value('model/optimize_model', True, bool)
|
|
}
|
|
self.model_config.set_config(model_config)
|
|
|
|
# Load UI preferences
|
|
dark_mode = self.settings.value('ui/dark_mode', True, bool)
|
|
if dark_mode:
|
|
self.ui_preferences.dark_radio.setChecked(True)
|
|
else:
|
|
self.ui_preferences.light_radio.setChecked(True)
|
|
|
|
@Slot()
|
|
def apply_settings(self):
|
|
"""Apply current settings"""
|
|
settings_data = self.get_all_settings()
|
|
self.settings_changed.emit(settings_data)
|
|
|
|
@Slot()
|
|
def save_settings(self):
|
|
"""Save settings to QSettings"""
|
|
# Save model configuration
|
|
model_config = self.model_config.get_config()
|
|
for key, value in model_config.items():
|
|
self.settings.setValue(f'model/{key}', value)
|
|
|
|
# Save UI preferences
|
|
self.settings.setValue('ui/dark_mode', self.ui_preferences.dark_radio.isChecked())
|
|
|
|
# Sync settings
|
|
self.settings.sync()
|
|
|
|
QMessageBox.information(self, "Settings Saved", "Settings have been saved successfully.")
|
|
save_configuration(settings_data, 'config.json')
|
|
|
|
@Slot()
|
|
def cancel_changes(self):
|
|
"""Cancel changes and reload settings"""
|
|
self.load_settings()
|
|
|
|
@Slot()
|
|
def reset_to_defaults(self):
|
|
"""Reset all settings to defaults"""
|
|
reply = QMessageBox.question(
|
|
self, "Reset Settings",
|
|
"Are you sure you want to reset all settings to defaults?",
|
|
QMessageBox.Yes | QMessageBox.No
|
|
)
|
|
|
|
if reply == QMessageBox.Yes:
|
|
self.settings.clear()
|
|
self.load_settings()
|
|
|
|
@Slot()
|
|
def export_settings(self):
|
|
"""Export settings to file"""
|
|
file_path, _ = QFileDialog.getSaveFileName(
|
|
self, "Export Settings", "",
|
|
"JSON Files (*.json);;All Files (*)"
|
|
)
|
|
|
|
if file_path:
|
|
settings_data = self.get_all_settings()
|
|
try:
|
|
with open(file_path, 'w') as f:
|
|
json.dump(settings_data, f, indent=2)
|
|
QMessageBox.information(self, "Export Successful", "Settings exported successfully.")
|
|
except Exception as e:
|
|
QMessageBox.critical(self, "Export Error", f"Failed to export settings:\n{str(e)}")
|
|
|
|
@Slot()
|
|
def import_settings(self):
|
|
"""Import settings from file"""
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
self, "Import Settings", "",
|
|
"JSON Files (*.json);;All Files (*)"
|
|
)
|
|
|
|
if file_path:
|
|
try:
|
|
with open(file_path, 'r') as f:
|
|
settings_data = json.load(f)
|
|
|
|
# Apply imported settings
|
|
self.apply_imported_settings(settings_data)
|
|
QMessageBox.information(self, "Import Successful", "Settings imported successfully.")
|
|
|
|
except Exception as e:
|
|
QMessageBox.critical(self, "Import Error", f"Failed to import settings:\n{str(e)}")
|
|
|
|
def get_all_settings(self):
|
|
"""Get all current settings as dictionary"""
|
|
return {
|
|
'model': self.model_config.get_config(),
|
|
'ui': {
|
|
'dark_mode': self.ui_preferences.dark_radio.isChecked(),
|
|
'language': self.ui_preferences.language_combo.currentText(),
|
|
'font_size': self.ui_preferences.font_size_spin.value(),
|
|
'animations': self.ui_preferences.animations_check.isChecked(),
|
|
'sound': self.ui_preferences.sound_check.isChecked()
|
|
}
|
|
}
|
|
|
|
def apply_imported_settings(self, settings_data):
|
|
"""Apply imported settings data"""
|
|
if 'model' in settings_data:
|
|
self.model_config.set_config(settings_data['model'])
|
|
|
|
if 'ui' in settings_data:
|
|
ui_settings = settings_data['ui']
|
|
if 'dark_mode' in ui_settings:
|
|
if ui_settings['dark_mode']:
|
|
self.ui_preferences.dark_radio.setChecked(True)
|
|
else:
|
|
self.ui_preferences.light_radio.setChecked(True)
|
|
|
|
@Slot(bool)
|
|
def on_theme_changed(self, dark_mode):
|
|
"""Handle theme change"""
|
|
self.apply_theme(dark_mode)
|
|
|
|
def apply_theme(self, dark_mode=True):
|
|
"""Apply theme to the view"""
|
|
if dark_mode:
|
|
self.setStyleSheet(f"""
|
|
QWidget {{
|
|
background-color: {MaterialColors.surface};
|
|
color: {MaterialColors.text_primary};
|
|
}}
|
|
QPushButton {{
|
|
background-color: {MaterialColors.primary};
|
|
color: {MaterialColors.text_on_primary};
|
|
border: none;
|
|
border-radius: 6px;
|
|
padding: 8px 16px;
|
|
}}
|
|
QPushButton:hover {{
|
|
background-color: {MaterialColors.primary_variant};
|
|
}}
|
|
""")
|
|
|
|
def display_timestamp(self, ts):
|
|
return format_timestamp(ts)
|
|
def display_duration(self, seconds):
|
|
return format_duration(seconds)
|