mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-29 17:32:17 -07:00
[PaletteEditor] Ensure directory is writeable, don't fall back to alternate palette.
Took 17 minutes
This commit is contained in:
parent
ae37762ee1
commit
6e41e3502a
3 changed files with 47 additions and 20 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
#include "palette_editor_dialog.h"
|
#include "palette_editor_dialog.h"
|
||||||
|
|
||||||
|
#include "../../client/settings/cache_settings.h"
|
||||||
#include "../theme_manager.h"
|
#include "../theme_manager.h"
|
||||||
#include "palette_generator.h"
|
#include "palette_generator.h"
|
||||||
#include "palette_grid_widget.h"
|
#include "palette_grid_widget.h"
|
||||||
|
|
@ -8,6 +9,8 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
@ -22,6 +25,16 @@ PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QSt
|
||||||
setMinimumSize(740, 220);
|
setMinimumSize(740, 220);
|
||||||
setupUi();
|
setupUi();
|
||||||
|
|
||||||
|
// 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()) {
|
||||||
|
saveDir = themeDirPath;
|
||||||
|
} else {
|
||||||
|
saveDir = QDir(SettingsCache::instance().getThemesPath()).absoluteFilePath(themeName);
|
||||||
|
QDir().mkpath(saveDir);
|
||||||
|
}
|
||||||
|
|
||||||
// Load both scheme configs upfront so switching is instant
|
// Load both scheme configs upfront so switching is instant
|
||||||
loadSchemes();
|
loadSchemes();
|
||||||
|
|
||||||
|
|
@ -185,9 +198,9 @@ void PaletteEditorDialog::retranslateUi()
|
||||||
applyBtn->setToolTip(tr("Preview this palette without saving to disk"));
|
applyBtn->setToolTip(tr("Preview this palette without saving to disk"));
|
||||||
saveBtn->setToolTip(tr("Write palette-%1.toml and reload the theme").arg(loadedScheme.toLower()));
|
saveBtn->setToolTip(tr("Write palette-%1.toml and reload the theme").arg(loadedScheme.toLower()));
|
||||||
|
|
||||||
if (themeDirPath.isEmpty()) {
|
if (saveDir.isEmpty() || !QFileInfo(saveDir).isWritable()) {
|
||||||
saveBtn->setEnabled(false);
|
saveBtn->setEnabled(false);
|
||||||
saveBtn->setToolTip(tr("Cannot save: this theme has no directory on disk"));
|
saveBtn->setToolTip(tr("Cannot save: this theme has no writable directory"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,20 +269,34 @@ void PaletteEditorDialog::onSave()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PaletteConfig cfg = paletteGrid->currentPaletteConfig();
|
// Snapshot the currently displayed scheme so unsaved edits are not lost.
|
||||||
|
workingConfig[loadedScheme] = paletteGrid->currentPaletteConfig();
|
||||||
|
|
||||||
if (!ThemeManager::savePaletteConfig(themeDirPath, loadedScheme, cfg)) {
|
// Persist every scheme that changed, not just the one on screen. Each scheme
|
||||||
QMessageBox::warning(this, tr("Save failed"),
|
// has its own file, so edits to the non-active scheme would otherwise be
|
||||||
tr("Could not write %1 to:\n%2").arg(PaletteConfig::fileName(loadedScheme), themeDirPath));
|
// silently discarded when the dialog closes.
|
||||||
return;
|
for (auto it = workingConfig.begin(); it != workingConfig.end(); ++it) {
|
||||||
|
const QString &scheme = it.key();
|
||||||
|
if (it.value().colors == savedConfig.value(scheme).colors) {
|
||||||
|
continue; // unchanged — leave the on-disk file alone
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ThemeManager::savePaletteConfig(saveDir, scheme, it.value())) {
|
||||||
|
QMessageBox::warning(this, tr("Save failed"),
|
||||||
|
tr("Could not write %1 to:\n%2").arg(PaletteConfig::fileName(scheme), saveDir));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeConfig globalCfg = ThemeConfig::fromThemeDir(themeDirPath);
|
// Keep the saved snapshot in sync so Reset behaves correctly afterwards.
|
||||||
globalCfg.colorScheme = loadedScheme;
|
for (auto it = workingConfig.begin(); it != workingConfig.end(); ++it) {
|
||||||
globalCfg.save(themeDirPath);
|
savedConfig[it.key()] = it.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeConfig globalCfg = ThemeConfig::fromThemeDir(saveDir);
|
||||||
|
globalCfg.colorScheme = loadedScheme;
|
||||||
|
globalCfg.save(saveDir);
|
||||||
|
|
||||||
savedConfig[loadedScheme] = cfg;
|
|
||||||
workingConfig[loadedScheme] = cfg;
|
|
||||||
themeManager->reloadCurrentTheme();
|
themeManager->reloadCurrentTheme();
|
||||||
accept();
|
accept();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,9 @@ private:
|
||||||
QString themeDirPath;
|
QString themeDirPath;
|
||||||
QString themeName;
|
QString themeName;
|
||||||
QString loadedScheme;
|
QString loadedScheme;
|
||||||
|
// Directory writes are directed to; may differ from themeDirPath when the
|
||||||
|
// latter is read-only (e.g. a built-in / system theme directory).
|
||||||
|
QString saveDir;
|
||||||
|
|
||||||
QMap<QString, PaletteConfig> workingConfig;
|
QMap<QString, PaletteConfig> workingConfig;
|
||||||
QMap<QString, PaletteConfig> savedConfig;
|
QMap<QString, PaletteConfig> savedConfig;
|
||||||
|
|
|
||||||
|
|
@ -245,14 +245,11 @@ PaletteConfig PaletteConfig::fromDefault(const QString &themeDirPath, const QStr
|
||||||
|
|
||||||
bool wantDark = colorScheme.compare("Dark", Qt::CaseInsensitive) == 0;
|
bool wantDark = colorScheme.compare("Dark", Qt::CaseInsensitive) == 0;
|
||||||
|
|
||||||
PaletteConfig cfg =
|
// Only the default file matching the requested scheme is used. Falling back
|
||||||
fromFile(dir.absoluteFilePath(wantDark ? "palette-default-dark.toml" : "palette-default-light.toml"));
|
// to the opposite scheme's default would silently apply dark colours to a
|
||||||
|
// "Light" scheme (or vice versa). Callers already fall back to the OS /
|
||||||
if (!cfg.hasPalette()) {
|
// application palette when no default palette is available.
|
||||||
cfg = fromFile(dir.absoluteFilePath(wantDark ? "palette-default-light.toml" : "palette-default-dark.toml"));
|
return fromFile(dir.absoluteFilePath(wantDark ? "palette-default-dark.toml" : "palette-default-light.toml"));
|
||||||
}
|
|
||||||
|
|
||||||
return cfg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPalette PaletteConfig::apply(QPalette base) const
|
QPalette PaletteConfig::apply(QPalette base) const
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue