Die drei Texte nutzten palette(mid) (dunkles Grau) und waren im dunklen Design kaum lesbar. Jetzt palette(text) (weiss im dunklen, dunkel im hellen Design). Der Update-Fortschrittsbalken bekommt eine helle Beschriftung und einen gut sichtbaren blauen Balken.
216 lines
8.6 KiB
Python
216 lines
8.6 KiB
Python
"""Einstellungen-Tab: Discord-RPC, Auto-Update und Start-Tab direkt in der App
|
|
bearbeitbar, ohne config.json von Hand anfassen zu muessen."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from PySide6.QtCore import Signal
|
|
from PySide6.QtWidgets import (
|
|
QCheckBox,
|
|
QComboBox,
|
|
QFormLayout,
|
|
QGroupBox,
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QLineEdit,
|
|
QMessageBox,
|
|
QProgressBar,
|
|
QPushButton,
|
|
QSpinBox,
|
|
QVBoxLayout,
|
|
QWidget,
|
|
)
|
|
|
|
from . import __version__ as APP_VERSION
|
|
from .config import APP_NAME, save_config
|
|
from .updater import GITHUB_REPO
|
|
|
|
# Helle Schrift fuer Versionsnummer, Update-Status und GitHub-Link. palette(text) ist die
|
|
# Standard-Textfarbe (im dunklen Design weiss, im hellen dunkel) - das fruehere
|
|
# palette(mid) war ein dunkles Grau, das auf dem dunklen Hintergrund kaum lesbar war.
|
|
_LIGHT_TEXT_STYLE = "color: palette(text);"
|
|
|
|
# Update-Fortschrittsbalken: helle Beschriftung und gut sichtbarer Balken. Sobald ein
|
|
# Stylesheet gesetzt ist, zeichnet Qt den Balken nicht mehr mit dem nativen Stil - deshalb
|
|
# hier Rahmen, Hintergrund und Balken (chunk) vollstaendig angegeben.
|
|
_PROGRESS_BAR_STYLE = """
|
|
QProgressBar {
|
|
color: palette(text);
|
|
background-color: palette(base);
|
|
border: 1px solid palette(mid);
|
|
border-radius: 4px;
|
|
text-align: center;
|
|
}
|
|
QProgressBar::chunk {
|
|
background-color: #2f81f7;
|
|
border-radius: 3px;
|
|
}
|
|
"""
|
|
|
|
|
|
class SettingsTab(QWidget):
|
|
"""Speichert Aenderungen sofort in config.json und meldet sie per Signal an
|
|
MainWindow, damit Discord-RPC/Auto-Update ohne Neustart neu konfiguriert werden."""
|
|
|
|
settingsSaved = Signal(dict)
|
|
checkUpdatesRequested = Signal()
|
|
installUpdateRequested = Signal()
|
|
|
|
def __init__(self, config: dict[str, Any], parent=None):
|
|
super().__init__(parent)
|
|
self._config = config
|
|
|
|
outer = QVBoxLayout(self)
|
|
outer.setContentsMargins(32, 28, 32, 28)
|
|
outer.setSpacing(18)
|
|
|
|
header = QVBoxLayout()
|
|
header.setSpacing(2)
|
|
title = QLabel(f"{APP_NAME}-Einstellungen")
|
|
title.setStyleSheet("font-size: 20px; font-weight: 600;")
|
|
header.addWidget(title)
|
|
version_label = QLabel(f"Version {APP_VERSION}")
|
|
version_label.setStyleSheet(_LIGHT_TEXT_STYLE)
|
|
header.addWidget(version_label)
|
|
outer.addLayout(header)
|
|
|
|
discord_cfg = config.get("discord", {})
|
|
discord_box = QGroupBox("Discord Rich Presence")
|
|
discord_form = QFormLayout(discord_box)
|
|
self._discord_enabled = QCheckBox("Aktiviert")
|
|
self._discord_enabled.setChecked(bool(discord_cfg.get("enabled", True)))
|
|
self._client_id = QLineEdit(str(discord_cfg.get("client_id", "")))
|
|
self._client_id.setPlaceholderText("Discord Application Client-ID")
|
|
self._discord_interval = QSpinBox()
|
|
# Minimum 15s: Discord ignoriert Rich-Presence-Updates, die haeufiger kommen,
|
|
# stillschweigend (fuehrt zu "eingefrorenem" Bild/Fortschrittsbalken).
|
|
self._discord_interval.setRange(15, 120)
|
|
self._discord_interval.setSuffix(" s")
|
|
self._discord_interval.setValue(max(15, int(discord_cfg.get("update_interval_seconds", 15))))
|
|
self._show_idle = QCheckBox("Status anzeigen, wenn gerade nichts läuft")
|
|
self._show_idle.setChecked(bool(discord_cfg.get("show_idle_presence", True)))
|
|
discord_form.addRow(self._discord_enabled)
|
|
discord_form.addRow("Client-ID:", self._client_id)
|
|
discord_form.addRow("Update-Intervall:", self._discord_interval)
|
|
discord_form.addRow(self._show_idle)
|
|
outer.addWidget(discord_box)
|
|
|
|
updates_cfg = config.get("updates", {})
|
|
update_box = QGroupBox("Automatische Updates")
|
|
update_form = QFormLayout(update_box)
|
|
self._updates_enabled = QCheckBox("Aktiviert")
|
|
self._updates_enabled.setChecked(bool(updates_cfg.get("enabled", True)))
|
|
self._check_interval = QSpinBox()
|
|
self._check_interval.setRange(1, 168)
|
|
self._check_interval.setSuffix(" h")
|
|
self._check_interval.setValue(int(updates_cfg.get("check_interval_hours", 6)))
|
|
update_form.addRow(self._updates_enabled)
|
|
update_form.addRow("Prüfintervall:", self._check_interval)
|
|
|
|
update_actions = QHBoxLayout()
|
|
self._check_updates_btn = QPushButton("Jetzt nach Updates suchen")
|
|
self._check_updates_btn.clicked.connect(self.checkUpdatesRequested.emit)
|
|
update_actions.addWidget(self._check_updates_btn)
|
|
self._install_update_btn = QPushButton("Update installieren")
|
|
self._install_update_btn.setVisible(False)
|
|
self._install_update_btn.clicked.connect(self.installUpdateRequested.emit)
|
|
update_actions.addWidget(self._install_update_btn)
|
|
update_actions.addStretch(1)
|
|
update_form.addRow(update_actions)
|
|
|
|
self._update_status_label = QLabel("")
|
|
self._update_status_label.setStyleSheet(_LIGHT_TEXT_STYLE)
|
|
self._update_status_label.setWordWrap(True)
|
|
update_form.addRow(self._update_status_label)
|
|
|
|
self._update_progress = QProgressBar()
|
|
self._update_progress.setRange(0, 100)
|
|
self._update_progress.setTextVisible(True)
|
|
self._update_progress.setStyleSheet(_PROGRESS_BAR_STYLE)
|
|
self._update_progress.setVisible(False)
|
|
update_form.addRow(self._update_progress)
|
|
|
|
outer.addWidget(update_box)
|
|
|
|
general_box = QGroupBox("Allgemein")
|
|
general_form = QFormLayout(general_box)
|
|
self._start_tab = QComboBox()
|
|
self._start_tab.addItem("YouTube", "youtube")
|
|
self._start_tab.addItem("YouTube Music", "music")
|
|
idx = self._start_tab.findData(config.get("start_tab", "youtube"))
|
|
self._start_tab.setCurrentIndex(max(0, idx))
|
|
general_form.addRow("Beim Start öffnen:", self._start_tab)
|
|
outer.addWidget(general_box)
|
|
|
|
button_row = QHBoxLayout()
|
|
save_btn = QPushButton("Speichern")
|
|
save_btn.clicked.connect(self._on_save)
|
|
button_row.addWidget(save_btn)
|
|
button_row.addStretch(1)
|
|
outer.addLayout(button_row)
|
|
|
|
info = QLabel(f"github.com/{GITHUB_REPO}")
|
|
info.setStyleSheet(_LIGHT_TEXT_STYLE)
|
|
outer.addWidget(info)
|
|
|
|
outer.addStretch(1)
|
|
|
|
def _on_save(self) -> None:
|
|
self._config.setdefault("discord", {})
|
|
self._config.setdefault("updates", {})
|
|
|
|
self._config["discord"]["enabled"] = self._discord_enabled.isChecked()
|
|
self._config["discord"]["client_id"] = self._client_id.text().strip()
|
|
self._config["discord"]["update_interval_seconds"] = self._discord_interval.value()
|
|
self._config["discord"]["show_idle_presence"] = self._show_idle.isChecked()
|
|
|
|
self._config["updates"]["enabled"] = self._updates_enabled.isChecked()
|
|
self._config["updates"]["check_interval_hours"] = self._check_interval.value()
|
|
|
|
self._config["start_tab"] = self._start_tab.currentData()
|
|
|
|
save_config(self._config)
|
|
self.settingsSaved.emit(self._config)
|
|
QMessageBox.information(
|
|
self,
|
|
"Gespeichert",
|
|
"Einstellungen gespeichert und übernommen (Discord-Verbindung wurde "
|
|
"mit den neuen Werten neu gestartet).",
|
|
)
|
|
|
|
# ----------------------------------------------------- Update-Status (von MainWindow)
|
|
|
|
def set_checking(self) -> None:
|
|
self._check_updates_btn.setEnabled(False)
|
|
self._install_update_btn.setVisible(False)
|
|
self._update_progress.setVisible(False)
|
|
self._update_status_label.setText("Suche nach Updates …")
|
|
|
|
def set_check_done(self) -> None:
|
|
self._check_updates_btn.setEnabled(True)
|
|
|
|
def set_update_status(self, text: str) -> None:
|
|
self._update_status_label.setText(text)
|
|
|
|
def show_update_available(self, version: str) -> None:
|
|
self._update_status_label.setText(f"Neue Version verfügbar: {version}")
|
|
self._install_update_btn.setVisible(True)
|
|
|
|
def hide_install_button(self) -> None:
|
|
self._install_update_btn.setVisible(False)
|
|
|
|
def set_download_progress(self, percent: int) -> None:
|
|
"""percent: 0-100 fuer einen konkreten Fortschritt, -1 fuer unbestimmt
|
|
(z.B. waehrend Entpacken/Installieren), negativ->versteckt den Balken nicht
|
|
automatisch - dafuer set_progress_hidden() aufrufen."""
|
|
if percent < 0:
|
|
self._update_progress.setRange(0, 0) # "laufender" Balken ohne Prozentzahl
|
|
else:
|
|
self._update_progress.setRange(0, 100)
|
|
self._update_progress.setValue(percent)
|
|
self._update_progress.setVisible(True)
|
|
|
|
def set_progress_hidden(self) -> None:
|
|
self._update_progress.setVisible(False)
|
|
self._update_progress.setRange(0, 100)
|