Address comments

Took 8 minutes
This commit is contained in:
Lukas Brübach 2026-07-23 04:36:47 +02:00
parent 74419231f7
commit 79ad3e1384
4 changed files with 46 additions and 17 deletions

View file

@ -15,11 +15,27 @@
#include <QFrame>
#include <QGuiApplication>
#include <QLabel>
#include <QLoggingCategory>
#include <QMessageBox>
#include <QPushButton>
#include <QStyleHints>
#include <QTimer>
// Probe whether a directory is truly writable by trying to create and remove a
// temporary file. QFileInfo::isWritable() on a directory is unreliable (notably
// on Windows where UAC VirtualStore can make a system dir appear writable).
static bool isDirReallyWritable(const QString &dirPath)
{
const QString probe = QDir(dirPath).absoluteFilePath(".cockatrice_write_test");
QFile f(probe);
if (!f.open(QIODevice::WriteOnly)) {
return false;
}
f.close();
f.remove();
return true;
}
PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QString &_themeName, QWidget *parent)
: QDialog(parent), themeDirPath(_themeDirPath), themeName(_themeName)
{
@ -29,11 +45,13 @@ PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QSt
// Resolve a writable directory for saving. Built-in (Default / Fusion) and
// other read-only theme directories must be customised in the user-writable
// themes directory; otherwise the write would fail or be lost on upgrade.
if (!themeDirPath.isEmpty() && QFileInfo(themeDirPath).isWritable()) {
if (!themeDirPath.isEmpty() && isDirReallyWritable(themeDirPath)) {
saveDir = themeDirPath;
} else {
saveDir = QDir(SettingsCache::instance().getThemesPath()).absoluteFilePath(themeName);
QDir().mkpath(saveDir);
if (!QDir().mkpath(saveDir)) {
qWarning() << "Failed to create palette save directory:" << saveDir;
}
}
// Load both scheme configs upfront so switching is instant
@ -195,7 +213,7 @@ void PaletteEditorDialog::retranslateUi()
resetBtn->setToolTip(tr("Discard unsaved edits and restore the last saved palette"));
saveBtn->setToolTip(tr("Write palette-%1.toml and reload the theme").arg(loadedScheme.toLower()));
if (saveDir.isEmpty() || !QFileInfo(saveDir).isWritable()) {
if (saveDir.isEmpty() || !isDirReallyWritable(saveDir)) {
saveBtn->setEnabled(false);
saveBtn->setToolTip(tr("Cannot save: this theme has no writable directory"));
}
@ -307,11 +325,10 @@ void PaletteEditorDialog::onRevertToDefault()
{
// Delete this scheme's custom palette file so the theme falls back to its
// default (or, when it ships none, the application palette).
const QString fileName = PaletteConfig::fileName(loadedScheme);
QFile::remove(QDir(saveDir).absoluteFilePath(fileName));
if (!themeDirPath.isEmpty() && themeDirPath != saveDir) {
QFile::remove(QDir(themeDirPath).absoluteFilePath(fileName));
}
// Note: shipped defaults use palette-default-<scheme>.toml so this only
// removes user-written custom palette files; the theme author's defaults
// are left untouched.
QFile::remove(QDir(saveDir).absoluteFilePath(PaletteConfig::fileName(loadedScheme)));
// Reload the live theme so the revert takes effect immediately.
themeManager->reloadCurrentTheme();

View file

@ -89,5 +89,7 @@ int QuickSetupPanel::intensity() const
void QuickSetupPanel::setAccentColor(const QColor &c)
{
accentButton->blockSignals(true);
accentButton->setColor(c);
}
accentButton->blockSignals(false);
}

View file

@ -88,4 +88,4 @@ private:
QLabel *intensityPercentageLabel;
};
#endif // COCKATRICE_QUICK_SETUP_PANEL_H
#endif // COCKATRICE_QUICK_SETUP_PANEL_H

View file

@ -92,18 +92,18 @@ struct PaletteColorInfo
ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
{
defaultStyleName = qApp->style()->objectName();
// On Windows, Qt may report the legacy "windowsvista" style as the default.
// Prefer the modern "windows11" style when it is available; "windowsvista"
// remains selectable through the per-theme style setting.
if (defaultStyleName.compare("windowsvista", Qt::CaseInsensitive) == 0 &&
QStyleFactory::keys().contains("windows11", Qt::CaseInsensitive)) {
defaultStyleName = "windows11";
//! \todo Workaround for windows11 style being broken.
if (defaultStyleName == "windows11") {
defaultStyleName = "windowsvista";
}
// Capture the untouched application palette before any theme is applied.
defaultPalette = qApp->palette();
ensureThemeDirectoryExists();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &ThemeManager::themeChangedSlot);
connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this] {
defaultPalette = qApp->palette();
themeChangedSlot();
});
#endif
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this, &ThemeManager::themeChangedSlot);
themeChangedSlot();
@ -402,6 +402,16 @@ void ThemeManager::themeChangedSlot()
if (!dirPath.isEmpty()) {
resources << dir.absolutePath();
}
// When the resolved dir is a user copy (e.g. user/<theme>), also
// include the system theme dir as a fallback so shipped assets like
// zones/*.png and style.css still resolve for themes that ship only
// those files (e.g. Leather, Plasma, Fabric, VelvetMarble).
const QString sysPath = QDir(systemThemesBasePath()).absoluteFilePath(themeName);
if (sysPath != dirPath && QDir(sysPath).exists()) {
resources << sysPath;
}
resources << DEFAULT_RESOURCE_PATHS;
QDir::setSearchPaths("theme", resources);