Files
OpCore-Simplify/Scripts/pages/settings_page.py
Hoang Hong Quan 0e608a56ce Add GUI Support for OpCore Simplify (#512)
* Refactor OpCore-Simplify to GUI version

* New ConfigEditor

* Add requirement checks and installation in launchers

* Add GitHub Actions workflow to generate manifest.json

* Set compression level for asset

* Skip .git and __pycache__ folders

* Refactor update process to include integrity checker

* Add SMBIOS model selection

* Update README.md

* Update to main branch
2025-12-30 14:19:47 +07:00

271 lines
10 KiB
Python

import os
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QFileDialog
)
from PyQt6.QtCore import Qt
from qfluentwidgets import (
ScrollArea, BodyLabel, PushButton, LineEdit, FluentIcon,
SettingCardGroup, SwitchSettingCard, ComboBoxSettingCard,
PushSettingCard, SpinBox,
OptionsConfigItem, OptionsValidator, HyperlinkCard,
StrongBodyLabel, CaptionLabel, SettingCard, SubtitleLabel,
setTheme, Theme
)
from Scripts.custom_dialogs import show_confirmation
from Scripts.styles import COLORS, SPACING
class SettingsPage(ScrollArea):
def __init__(self, parent):
super().__init__(parent)
self.setObjectName("settingsPage")
self.controller = parent
self.scrollWidget = QWidget()
self.expandLayout = QVBoxLayout(self.scrollWidget)
self.settings = self.controller.backend.settings
self.setWidget(self.scrollWidget)
self.setWidgetResizable(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self.enableTransparentBackground()
self._init_ui()
def _init_ui(self):
self.expandLayout.setContentsMargins(SPACING["xxlarge"], SPACING["xlarge"], SPACING["xxlarge"], SPACING["xlarge"])
self.expandLayout.setSpacing(SPACING["large"])
header_container = QWidget()
header_layout = QVBoxLayout(header_container)
header_layout.setContentsMargins(0, 0, 0, 0)
header_layout.setSpacing(SPACING["tiny"])
title_label = SubtitleLabel("Settings")
header_layout.addWidget(title_label)
subtitle_label = BodyLabel("Configure OpCore Simplify preferences")
subtitle_label.setStyleSheet("color: {};".format(COLORS["text_secondary"]))
header_layout.addWidget(subtitle_label)
self.expandLayout.addWidget(header_container)
self.expandLayout.addSpacing(SPACING["medium"])
self.build_output_group = self.create_build_output_group()
self.expandLayout.addWidget(self.build_output_group)
self.macos_group = self.create_macos_version_group()
self.expandLayout.addWidget(self.macos_group)
#self.appearance_group = self.create_appearance_group()
#self.expandLayout.addWidget(self.appearance_group)
self.update_group = self.create_update_settings_group()
self.expandLayout.addWidget(self.update_group)
self.advanced_group = self.create_advanced_group()
self.expandLayout.addWidget(self.advanced_group)
self.help_group = self.create_help_group()
self.expandLayout.addWidget(self.help_group)
self.bottom_widget = QWidget()
bottom_layout = QHBoxLayout(self.bottom_widget)
bottom_layout.setContentsMargins(0, SPACING["large"], 0, SPACING["large"])
bottom_layout.setSpacing(SPACING["medium"])
bottom_layout.addStretch()
reset_btn = PushButton("Reset All to Defaults", self.bottom_widget)
reset_btn.setIcon(FluentIcon.CANCEL)
reset_btn.clicked.connect(self.reset_to_defaults)
bottom_layout.addWidget(reset_btn)
self.expandLayout.addWidget(self.bottom_widget)
for card in self.findChildren(SettingCard):
card.setIconSize(18, 18)
def _update_widget_value(self, widget, value):
if widget is None:
return
if isinstance(widget, SwitchSettingCard):
widget.switchButton.setChecked(value)
elif isinstance(widget, (ComboBoxSettingCard, OptionsConfigItem)):
widget.setValue(value)
elif isinstance(widget, SpinBox):
widget.setValue(value)
elif isinstance(widget, LineEdit):
widget.setText(value)
elif isinstance(widget, PushSettingCard):
widget.setContent(value or "Use temporary directory (default)")
def create_build_output_group(self):
group = SettingCardGroup("Build Output", self.scrollWidget)
self.output_dir_card = PushSettingCard(
"Browse",
FluentIcon.FOLDER,
"Output Directory",
self.settings.get("build_output_directory") or "Use temporary directory (default)",
group
)
self.output_dir_card.setObjectName("build_output_directory")
self.output_dir_card.clicked.connect(self.browse_output_directory)
group.addSettingCard(self.output_dir_card)
return group
def create_macos_version_group(self):
group = SettingCardGroup("macOS Version", self.scrollWidget)
self.include_beta_card = SwitchSettingCard(
FluentIcon.UPDATE,
"Include beta version",
"Show major beta macOS versions in version selection menus. Enable to test new macOS releases.",
configItem=None,
parent=group
)
self.include_beta_card.setObjectName("include_beta_versions")
self.include_beta_card.switchButton.setChecked(self.settings.get_include_beta_versions())
self.include_beta_card.switchButton.checkedChanged.connect(lambda checked: self.settings.set("include_beta_versions", checked))
group.addSettingCard(self.include_beta_card)
return group
def create_appearance_group(self):
group = SettingCardGroup("Appearance", self.scrollWidget)
theme_values = [
"Light",
#"Dark",
]
theme_value = self.settings.get_theme()
if theme_value not in theme_values:
theme_value = "Light"
self.theme_config = OptionsConfigItem(
"Appearance",
"Theme",
theme_value,
OptionsValidator(theme_values)
)
def on_theme_changed(value):
self.settings.set("theme", value)
if value == "Dark":
setTheme(Theme.DARK)
else:
setTheme(Theme.LIGHT)
self.theme_config.valueChanged.connect(on_theme_changed)
self.theme_card = ComboBoxSettingCard(
self.theme_config,
FluentIcon.BRUSH,
"Theme",
"Selects the application color theme.",
theme_values,
group
)
self.theme_card.setObjectName("theme")
group.addSettingCard(self.theme_card)
return group
def create_update_settings_group(self):
group = SettingCardGroup("Updates & Downloads", self.scrollWidget)
self.auto_update_card = SwitchSettingCard(
FluentIcon.UPDATE,
"Check for updates on startup",
"Automatically checks for new OpCore Simplify updates when the application launches to keep you up to date",
configItem=None,
parent=group
)
self.auto_update_card.setObjectName("auto_update_check")
self.auto_update_card.switchButton.setChecked(self.settings.get_auto_update_check())
self.auto_update_card.switchButton.checkedChanged.connect(lambda checked: self.settings.set("auto_update_check", checked))
group.addSettingCard(self.auto_update_card)
return group
def create_advanced_group(self):
group = SettingCardGroup("Advanced Settings", self.scrollWidget)
self.debug_logging_card = SwitchSettingCard(
FluentIcon.DEVELOPER_TOOLS,
"Enable debug logging",
"Enables detailed debug logging throughout the application for advanced troubleshooting and diagnostics",
configItem=None,
parent=group
)
self.debug_logging_card.setObjectName("enable_debug_logging")
self.debug_logging_card.switchButton.setChecked(self.settings.get_enable_debug_logging())
self.debug_logging_card.switchButton.checkedChanged.connect(lambda checked: self.settings.set("enable_debug_logging", checked))
group.addSettingCard(self.debug_logging_card)
return group
def create_help_group(self):
group = SettingCardGroup("Help & Documentation", self.scrollWidget)
self.opencore_docs_card = HyperlinkCard(
"https://dortania.github.io/OpenCore-Install-Guide/",
"OpenCore Install Guide",
FluentIcon.BOOK_SHELF,
"OpenCore Documentation",
"Complete guide for installing macOS with OpenCore",
group
)
group.addSettingCard(self.opencore_docs_card)
self.troubleshoot_card = HyperlinkCard(
"https://dortania.github.io/OpenCore-Install-Guide/troubleshooting/troubleshooting.html",
"Troubleshooting",
FluentIcon.HELP,
"Troubleshooting Guide",
"Solutions to common OpenCore installation issues",
group
)
group.addSettingCard(self.troubleshoot_card)
self.github_card = HyperlinkCard(
"https://github.com/lzhoang2801/OpCore-Simplify",
"View on GitHub",
FluentIcon.GITHUB,
"OpCore-Simplify Repository",
"Report issues, contribute, or view the source code",
group
)
group.addSettingCard(self.github_card)
return group
def browse_output_directory(self):
folder = QFileDialog.getExistingDirectory(
self,
"Select Build Output Directory",
os.path.expanduser("~")
)
if folder:
self.settings.set("build_output_directory", folder)
self.output_dir_card.setContent(folder)
self.controller.update_status("Output directory updated successfully", "success")
def reset_to_defaults(self):
result = show_confirmation("Reset Settings", "Are you sure you want to reset all settings to their default values?")
if result:
self.settings.settings = self.settings.defaults.copy()
self.settings.save_settings()
for widget in self.findChildren(QWidget):
key = widget.objectName()
if key and key in self.settings.defaults:
default_value = self.settings.defaults.get(key)
self._update_widget_value(widget, default_value)
self.controller.update_status("All settings reset to defaults", "success")