Don't change real theme when editing.

This commit is contained in:
John Preston 2019-09-05 09:51:46 +03:00
parent 03bdd80b2f
commit 7485f0c960
9 changed files with 175 additions and 113 deletions

View File

@ -1602,6 +1602,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_theme_editor_save_palette" = "Save palette file"; "lng_theme_editor_save_palette" = "Save palette file";
"lng_theme_editor_choose_name" = "Save theme file"; "lng_theme_editor_choose_name" = "Save theme file";
"lng_theme_editor_error" = "The editor encountered an error :( See 'log.txt' for details."; "lng_theme_editor_error" = "The editor encountered an error :( See 'log.txt' for details.";
"lng_theme_editor_sure_close" = "Are you sure you want to close the editor? Your changes won't be saved.";
"lng_theme_editor_done" = "Theme exported successfully!"; "lng_theme_editor_done" = "Theme exported successfully!";
"lng_theme_editor_title" = "Edit color palette"; "lng_theme_editor_title" = "Edit color palette";
"lng_theme_editor_export_button" = "Export theme"; "lng_theme_editor_export_button" = "Export theme";

View File

@ -143,7 +143,7 @@ Application::~Application() {
stopWebLoadManager(); stopWebLoadManager();
App::deinitMedia(); App::deinitMedia();
Window::Theme::Unload(); Window::Theme::Uninitialize();
Media::Player::finish(_audio.get()); Media::Player::finish(_audio.get());
style::stopManager(); style::stopManager();

View File

@ -999,6 +999,9 @@ void SetupDefaultThemes(not_null<Ui::VerticalLayout*> container) {
const auto chosen = [] { const auto chosen = [] {
const auto &object = Window::Theme::Background()->themeObject(); const auto &object = Window::Theme::Background()->themeObject();
if (object.cloud.id) {
return Type(-1);
}
for (const auto &scheme : kSchemesList) { for (const auto &scheme : kSchemesList) {
if (object.pathAbsolute == scheme.path) { if (object.pathAbsolute == scheme.path) {
return scheme.type; return scheme.type;

View File

@ -674,7 +674,7 @@ FileKey _themeKeyDay = 0;
FileKey _themeKeyNight = 0; FileKey _themeKeyNight = 0;
// Theme key legacy may be read in start() with settings. // Theme key legacy may be read in start() with settings.
// But it should be moved to keyDay or keyNight inside loadTheme() // But it should be moved to keyDay or keyNight inside InitialLoadTheme()
// and never used after. // and never used after.
FileKey _themeKeyLegacy = 0; FileKey _themeKeyLegacy = 0;
@ -2554,7 +2554,7 @@ void finish() {
} }
} }
void loadTheme(); void InitialLoadTheme();
void readLangPack(); void readLangPack();
void start() { void start() {
@ -2612,7 +2612,7 @@ void start() {
_oldSettingsVersion = settingsData.version; _oldSettingsVersion = settingsData.version;
_settingsSalt = salt; _settingsSalt = salt;
loadTheme(); InitialLoadTheme();
readLangPack(); readLangPack();
applyReadContext(std::move(context)); applyReadContext(std::move(context));
@ -4259,12 +4259,12 @@ Window::Theme::Saved readThemeUsingKey(FileKey key) {
return result; return result;
} }
QString loadThemeUsingKey(FileKey key) { std::optional<QString> InitialLoadThemeUsingKey(FileKey key) {
auto read = readThemeUsingKey(key); auto read = readThemeUsingKey(key);
const auto result = read.object.pathAbsolute; const auto result = read.object.pathAbsolute;
if (read.object.content.isEmpty() if (read.object.content.isEmpty()
|| !Window::Theme::Load(std::move(read))) { || !Window::Theme::Initialize(std::move(read))) {
return QString(); return std::nullopt;
} }
return result; return result;
} }
@ -4333,7 +4333,7 @@ void clearTheme() {
writeTheme(Window::Theme::Saved()); writeTheme(Window::Theme::Saved());
} }
void loadTheme() { void InitialLoadTheme() {
const auto key = (_themeKeyLegacy != 0) const auto key = (_themeKeyLegacy != 0)
? _themeKeyLegacy ? _themeKeyLegacy
: (Window::Theme::IsNightMode() : (Window::Theme::IsNightMode()
@ -4341,9 +4341,9 @@ void loadTheme() {
: _themeKeyDay); : _themeKeyDay);
if (!key) { if (!key) {
return; return;
} else if (const auto path = loadThemeUsingKey(key); !path.isEmpty()) { } else if (const auto path = InitialLoadThemeUsingKey(key)) {
if (_themeKeyLegacy) { if (_themeKeyLegacy) {
Window::Theme::SetNightModeValue(path Window::Theme::SetNightModeValue(*path
== Window::Theme::NightThemePath()); == Window::Theme::NightThemePath());
(Window::Theme::IsNightMode() (Window::Theme::IsNightMode()
? _themeKeyNight ? _themeKeyNight

View File

@ -233,37 +233,6 @@ void applyBackground(QImage &&background, bool tiled, Instance *out) {
} }
} }
bool loadThemeFromCache(const QByteArray &content, const Cached &cache) {
if (cache.paletteChecksum != style::palette::Checksum()) {
return false;
}
if (cache.contentChecksum != hashCrc32(content.constData(), content.size())) {
return false;
}
QImage background;
if (!cache.background.isEmpty()) {
QDataStream stream(cache.background);
QImageReader reader(stream.device());
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (!reader.read(&background) || background.isNull()) {
return false;
}
}
if (!style::main_palette::load(cache.colors)) {
return false;
}
Background()->saveAdjustableColors();
if (!background.isNull()) {
applyBackground(std::move(background), cache.tiled, nullptr);
}
return true;
}
enum class LoadResult { enum class LoadResult {
Loaded, Loaded,
Failed, Failed,
@ -300,17 +269,24 @@ bool loadBackground(zlib::FileToRead &file, QByteArray *outBackground, bool *out
bool loadTheme( bool loadTheme(
const QByteArray &content, const QByteArray &content,
const std::optional<QByteArray> &editedPalette,
Cached &cache, Cached &cache,
const Colorizer &colorizer, const Colorizer &colorizer,
Instance *out = nullptr) { Instance *out = nullptr) {
cache = Cached(); cache = Cached();
zlib::FileToRead file(content); zlib::FileToRead file(content);
const auto emptyColorizer = Colorizer();
const auto &applyColorizer = editedPalette ? emptyColorizer : colorizer;
unz_global_info globalInfo = { 0 }; unz_global_info globalInfo = { 0 };
file.getGlobalInfo(&globalInfo); file.getGlobalInfo(&globalInfo);
if (file.error() == UNZ_OK) { if (file.error() == UNZ_OK) {
auto schemeContent = file.readFileContent("colors.tdesktop-theme", zlib::kCaseInsensitive, kThemeSchemeSizeLimit); auto schemeContent = editedPalette.value_or(QByteArray());
if (file.error() == UNZ_END_OF_LIST_OF_FILE) { if (schemeContent.isEmpty()) {
schemeContent = file.readFileContent("colors.tdesktop-theme", zlib::kCaseInsensitive, kThemeSchemeSizeLimit);
}
if (schemeContent.isEmpty()) {
file.clearError(); file.clearError();
schemeContent = file.readFileContent("colors.tdesktop-palette", zlib::kCaseInsensitive, kThemeSchemeSizeLimit); schemeContent = file.readFileContent("colors.tdesktop-palette", zlib::kCaseInsensitive, kThemeSchemeSizeLimit);
} }
@ -318,7 +294,7 @@ bool loadTheme(
LOG(("Theme Error: could not read 'colors.tdesktop-theme' or 'colors.tdesktop-palette' in the theme file.")); LOG(("Theme Error: could not read 'colors.tdesktop-theme' or 'colors.tdesktop-palette' in the theme file."));
return false; return false;
} }
if (!loadColorScheme(schemeContent, colorizer, out)) { if (!loadColorScheme(schemeContent, applyColorizer, out)) {
return false; return false;
} }
Background()->saveAdjustableColors(); Background()->saveAdjustableColors();
@ -357,7 +333,7 @@ bool loadTheme(
} }
} else { } else {
// Looks like it is not a .zip theme. // Looks like it is not a .zip theme.
if (!loadColorScheme(content, colorizer, out)) { if (!loadColorScheme(editedPalette.value_or(content), applyColorizer, out)) {
return false; return false;
} }
Background()->saveAdjustableColors(); Background()->saveAdjustableColors();
@ -373,6 +349,74 @@ bool loadTheme(
return true; return true;
} }
bool InitializeFromCache(
const QByteArray &content,
const Cached &cache) {
if (cache.paletteChecksum != style::palette::Checksum()) {
return false;
}
if (cache.contentChecksum != hashCrc32(content.constData(), content.size())) {
return false;
}
QImage background;
if (!cache.background.isEmpty()) {
QDataStream stream(cache.background);
QImageReader reader(stream.device());
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (!reader.read(&background) || background.isNull()) {
return false;
}
}
if (!style::main_palette::load(cache.colors)) {
return false;
}
Background()->saveAdjustableColors();
if (!background.isNull()) {
applyBackground(std::move(background), cache.tiled, nullptr);
}
return true;
}
[[nodiscard]] std::optional<QByteArray> ReadEditingPalette() {
auto file = QFile(EditingPalettePath());
return file.open(QIODevice::ReadOnly)
? std::make_optional(file.readAll())
: std::nullopt;
}
bool InitializeFromSaved(Saved &&saved) {
if (saved.object.content.size() < 4) {
LOG(("Theme Error: Could not load theme from '%1' (%2)"
).arg(saved.object.pathRelative
).arg(saved.object.pathAbsolute));
return false;
}
const auto editing = ReadEditingPalette();
GlobalBackground.createIfNull();
if (!editing && InitializeFromCache(saved.object.content, saved.cache)) {
return true;
}
const auto colorizer = editing
? Colorizer()
: ColorizerForTheme(saved.object.pathAbsolute);
if (!loadTheme(saved.object.content, editing, saved.cache, colorizer)) {
return false;
}
if (editing) {
Background()->setIsEditingTheme(true);
} else {
Local::writeTheme(saved);
}
return true;
}
QImage validateBackgroundImage(QImage image) { QImage validateBackgroundImage(QImage image) {
if (image.format() != QImage::Format_ARGB32_Premultiplied) { if (image.format() != QImage::Format_ARGB32_Premultiplied) {
image = std::move(image).convertToFormat( image = std::move(image).convertToFormat(
@ -701,10 +745,18 @@ bool ChatBackground::adjustPaletteRequired() {
} }
bool ChatBackground::isEditingTheme() const { bool ChatBackground::isEditingTheme() const {
const auto &object = AreTestingTheme() return _editingTheme;
? GlobalApplying.data.object }
: _themeObject;
return IsEditingTheme(object.pathAbsolute); void ChatBackground::setIsEditingTheme(bool editing) {
if (_editingTheme == editing) {
return;
}
_editingTheme = editing;
if (!_editingTheme) {
reapplyWithNightMode(std::nullopt, _nightMode);
KeepApplied();
}
} }
void ChatBackground::adjustPaletteUsingBackground(const QImage &image) { void ChatBackground::adjustPaletteUsingBackground(const QImage &image) {
@ -971,12 +1023,14 @@ bool ChatBackground::nightMode() const {
return _nightMode; return _nightMode;
} }
void ChatBackground::toggleNightMode(std::optional<QString> themePath) { void ChatBackground::reapplyWithNightMode(
const auto settingDefault = themePath.has_value(); std::optional<QString> themePath,
bool newNightMode) {
const auto settingExactTheme = themePath.has_value();
const auto nightModeChanged = (newNightMode != _nightMode);
const auto oldNightMode = _nightMode; const auto oldNightMode = _nightMode;
const auto newNightMode = !_nightMode;
_nightMode = newNightMode; _nightMode = newNightMode;
auto read = settingDefault ? Saved() : Local::readThemeAfterSwitch(); auto read = settingExactTheme ? Saved() : Local::readThemeAfterSwitch();
auto path = read.object.pathAbsolute; auto path = read.object.pathAbsolute;
_nightMode = oldNightMode; _nightMode = oldNightMode;
@ -990,6 +1044,7 @@ void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
preview->instance.cached = std::move(read.cache); preview->instance.cached = std::move(read.cache);
const auto loaded = loadTheme( const auto loaded = loadTheme(
preview->object.content, preview->object.content,
std::nullopt,
preview->instance.cached, preview->instance.cached,
ColorizerForTheme(path), ColorizerForTheme(path),
&preview->instance); &preview->instance);
@ -1009,10 +1064,12 @@ void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
// Theme editor could have already reverted the testing of this toggle. // Theme editor could have already reverted the testing of this toggle.
if (AreTestingTheme()) { if (AreTestingTheme()) {
GlobalApplying.overrideKeep = [=] { GlobalApplying.overrideKeep = [=] {
_nightMode = newNightMode; if (nightModeChanged) {
_nightMode = newNightMode;
// Restore the value, it was set inside theme testing. // Restore the value, it was set inside theme testing.
(oldNightMode ? _tileNightValue : _tileDayValue) = oldTileValue; (oldNightMode ? _tileNightValue : _tileDayValue) = oldTileValue;
}
const auto saved = std::move(GlobalApplying.data); const auto saved = std::move(GlobalApplying.data);
if (!alreadyOnDisk) { if (!alreadyOnDisk) {
@ -1020,47 +1077,38 @@ void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
Local::writeTheme(saved); Local::writeTheme(saved);
} }
ClearApplying(); ClearApplying();
keepApplied(saved.object, settingDefault); keepApplied(saved.object, settingExactTheme);
if (tile() != _tileForRevert) { if (tile() != _tileForRevert) {
Local::writeUserSettings(); Local::writeUserSettings();
} }
Local::writeSettings(); if (nightModeChanged) {
if (!settingDefault && !Local::readBackground()) { Local::writeSettings();
}
if (!settingExactTheme && !Local::readBackground()) {
set(Data::ThemeWallPaper()); set(Data::ThemeWallPaper());
} }
}; };
} }
} }
void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
reapplyWithNightMode(themePath, !_nightMode);
}
ChatBackground *Background() { ChatBackground *Background() {
GlobalBackground.createIfNull(); GlobalBackground.createIfNull();
return GlobalBackground.data(); return GlobalBackground.data();
} }
bool Load(Saved &&saved) { bool Initialize(Saved &&saved) {
if (saved.object.content.size() < 4) { if (InitializeFromSaved(std::move(saved))) {
LOG(("Theme Error: Could not load theme from '%1' (%2)"
).arg(saved.object.pathRelative
).arg(saved.object.pathAbsolute));
return false;
}
GlobalBackground.createIfNull();
if (loadThemeFromCache(saved.object.content, saved.cache)) {
Background()->setThemeObject(saved.object); Background()->setThemeObject(saved.object);
return true; return true;
} }
return false;
const auto colorizer = ColorizerForTheme(saved.object.pathAbsolute);
if (!loadTheme(saved.object.content, saved.cache, colorizer)) {
return false;
}
Local::writeTheme(saved);
Background()->setThemeObject(saved.object);
return true;
} }
void Unload() { void Uninitialize() {
GlobalBackground.clear(); GlobalBackground.clear();
GlobalApplying = Applying(); GlobalApplying = Applying();
} }
@ -1098,30 +1146,13 @@ void ApplyDefaultWithPath(const QString &themePath) {
} }
} }
bool ApplyEditedPalette(const QString &path, const QByteArray &content) { bool ApplyEditedPalette(const QByteArray &content) {
Instance out; auto out = Instance();
if (!loadColorScheme(content, Colorizer(), &out)) { if (!loadColorScheme(content, Colorizer(), &out)) {
return false; return false;
} }
out.cached.colors = out.palette.save(); style::main_palette::apply(out.palette);
out.cached.paletteChecksum = style::palette::Checksum(); Background()->notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingEdit, Background()->tile()), true);
out.cached.contentChecksum = hashCrc32(
content.constData(),
content.size());
GlobalApplying.data.object.pathRelative = path.isEmpty()
? QString()
: QDir().relativeFilePath(path);
GlobalApplying.data.object.pathAbsolute = path.isEmpty()
? QString()
: QFileInfo(path).absoluteFilePath();
GlobalApplying.data.object.content = content;
GlobalApplying.data.cache = out.cached;
if (GlobalApplying.paletteForRevert.isEmpty()) {
GlobalApplying.paletteForRevert = style::main_palette::save();
}
Background()->setTestingTheme(std::move(out));
KeepApplied();
return true; return true;
} }
@ -1188,7 +1219,7 @@ bool LoadFromContent(
return false; return false;
} }
return loadTheme(content, out->cached, colorizer, out); return loadTheme(content, std::nullopt, out->cached, colorizer, out);
} }
bool LoadFromFile( bool LoadFromFile(
@ -1207,6 +1238,10 @@ QString EditingPalettePath() {
return cWorkingDir() + "tdata/editing-theme.tdesktop-palette"; return cWorkingDir() + "tdata/editing-theme.tdesktop-palette";
} }
void ClearEditingPalette() {
QFile(EditingPalettePath()).remove();
}
QColor CountAverageColor(const QImage &image) { QColor CountAverageColor(const QImage &image) {
Expects(image.format() == QImage::Format_ARGB32_Premultiplied); Expects(image.format() == QImage::Format_ARGB32_Premultiplied);

View File

@ -36,8 +36,8 @@ struct Saved {
Object object; Object object;
Cached cache; Cached cache;
}; };
bool Load(Saved &&saved); bool Initialize(Saved &&saved);
void Unload(); void Uninitialize();
struct Instance { struct Instance {
style::palette palette; style::palette palette;
@ -57,7 +57,7 @@ bool Apply(
const Data::CloudTheme &cloud = Data::CloudTheme()); const Data::CloudTheme &cloud = Data::CloudTheme());
bool Apply(std::unique_ptr<Preview> preview); bool Apply(std::unique_ptr<Preview> preview);
void ApplyDefaultWithPath(const QString &themePath); void ApplyDefaultWithPath(const QString &themePath);
bool ApplyEditedPalette(const QString &path, const QByteArray &content); bool ApplyEditedPalette(const QByteArray &content);
void KeepApplied(); void KeepApplied();
QString NightThemePath(); QString NightThemePath();
[[nodiscard]] bool IsNightMode(); [[nodiscard]] bool IsNightMode();
@ -68,6 +68,7 @@ void ToggleNightMode(const QString &themePath);
void Revert(); void Revert();
[[nodiscard]] QString EditingPalettePath(); [[nodiscard]] QString EditingPalettePath();
void ClearEditingPalette();
bool LoadFromFile( bool LoadFromFile(
const QString &file, const QString &file,
@ -86,12 +87,15 @@ struct BackgroundUpdate {
TestingTheme, TestingTheme,
RevertingTheme, RevertingTheme,
ApplyingTheme, ApplyingTheme,
ApplyingEdit,
}; };
BackgroundUpdate(Type type, bool tiled) : type(type), tiled(tiled) { BackgroundUpdate(Type type, bool tiled) : type(type), tiled(tiled) {
} }
[[nodiscard]] bool paletteChanged() const { [[nodiscard]] bool paletteChanged() const {
return (type == Type::TestingTheme || type == Type::RevertingTheme); return (type == Type::TestingTheme)
|| (type == Type::RevertingTheme)
|| (type == Type::ApplyingEdit);
} }
Type type; Type type;
bool tiled; bool tiled;
@ -115,6 +119,7 @@ public:
void setThemeObject(const Object &object); void setThemeObject(const Object &object);
[[nodiscard]] const Object &themeObject() const; [[nodiscard]] const Object &themeObject() const;
[[nodiscard]] bool isEditingTheme() const; [[nodiscard]] bool isEditingTheme() const;
void setIsEditingTheme(bool editing);
void reset(); void reset();
void setTestingTheme(Instance &&theme); void setTestingTheme(Instance &&theme);
@ -164,6 +169,9 @@ private:
void setNightModeValue(bool nightMode); void setNightModeValue(bool nightMode);
[[nodiscard]] bool nightMode() const; [[nodiscard]] bool nightMode() const;
void toggleNightMode(std::optional<QString> themePath); void toggleNightMode(std::optional<QString> themePath);
void reapplyWithNightMode(
std::optional<QString> themePath,
bool newNightMode);
void keepApplied(const Object &object, bool write); void keepApplied(const Object &object, bool write);
[[nodiscard]] bool isNonDefaultThemeOrBackground(); [[nodiscard]] bool isNonDefaultThemeOrBackground();
[[nodiscard]] bool isNonDefaultBackground(); [[nodiscard]] bool isNonDefaultBackground();
@ -191,6 +199,7 @@ private:
Object _themeObject; Object _themeObject;
QImage _themeImage; QImage _themeImage;
bool _themeTile = false; bool _themeTile = false;
bool _editingTheme = false;
Data::WallPaper _paperForRevert Data::WallPaper _paperForRevert
= Data::details::UninitializedWallPaper(); = Data::details::UninitializedWallPaper();

View File

@ -587,7 +587,7 @@ void Editor::Inner::applyEditing(const QString &name, const QString &copyOf, QCo
f.close(); f.close();
_applyingUpdate = true; _applyingUpdate = true;
if (!ApplyEditedPalette(_path, newContent)) { if (!ApplyEditedPalette(newContent)) {
LOG(("Theme Error: could not apply newly composed content :(")); LOG(("Theme Error: could not apply newly composed content :("));
error(); error();
return; return;
@ -652,7 +652,20 @@ Editor::Editor(QWidget*, not_null<Window::Controller*> window)
_inner->setScrollCallback([this](int top, int bottom) { _inner->setScrollCallback([this](int top, int bottom) {
_scroll->scrollToY(top, bottom); _scroll->scrollToY(top, bottom);
}); });
_close->setClickedCallback([this] { closeEditor(); }); _close->setClickedCallback([=] {
const auto box = std::make_shared<QPointer<BoxContent>>();
const auto close = crl::guard(this, [=] {
ClearEditingPalette();
closeEditor();
if (*box) {
(*box)->closeBox();
}
});
*box = _window->show(Box<ConfirmBox>(
tr::lng_theme_editor_sure_close(tr::now),
tr::lng_close(tr::now),
close));
});
_close->show(anim::type::instant); _close->show(anim::type::instant);
_select->resizeToWidth(st::windowMinWidth); _select->resizeToWidth(st::windowMinWidth);
@ -759,6 +772,7 @@ void Editor::paintEvent(QPaintEvent *e) {
void Editor::closeEditor() { void Editor::closeEditor() {
if (const auto window = App::wnd()) { if (const auto window = App::wnd()) {
window->showRightColumn(nullptr); window->showRightColumn(nullptr);
Background()->setIsEditingTheme(false);
} }
} }

View File

@ -233,11 +233,11 @@ QString BytesToUTF8(QLatin1String string) {
return QString::fromUtf8(string.data(), string.size()); return QString::fromUtf8(string.data(), string.size());
} }
void WriteDefaultPalette(const QString &path) { bool WriteDefaultPalette(const QString &path) {
QFile f(path); QFile f(path);
if (!f.open(QIODevice::WriteOnly)) { if (!f.open(QIODevice::WriteOnly)) {
LOG(("Theme Error: could not open '%1' for writing.").arg(path)); LOG(("Theme Error: could not open '%1' for writing.").arg(path));
return; return false;
} }
QTextStream stream(&f); QTextStream stream(&f);
@ -260,6 +260,7 @@ void WriteDefaultPalette(const QString &path) {
' ') ' ')
<< "\n"; << "\n";
} }
return true;
} }
[[nodiscard]] QString GenerateSlug() { [[nodiscard]] QString GenerateSlug() {
@ -489,14 +490,12 @@ void StartEditor(
not_null<Window::Controller*> window, not_null<Window::Controller*> window,
const Data::CloudTheme &cloud) { const Data::CloudTheme &cloud) {
const auto path = EditingPalettePath(); const auto path = EditingPalettePath();
if (!Local::copyThemeColorsToPalette(path)) { if (!Local::copyThemeColorsToPalette(path)
WriteDefaultPalette(path); && !WriteDefaultPalette(path)) {
}
if (!Apply(path, cloud)) {
window->show(Box<InformBox>(tr::lng_theme_editor_error(tr::now))); window->show(Box<InformBox>(tr::lng_theme_editor_error(tr::now)));
return; return;
} }
KeepApplied(); Background()->setIsEditingTheme(true);
window->showRightColumn(Box<Editor>(window)); window->showRightColumn(Box<Editor>(window));
} }

View File

@ -926,6 +926,7 @@ std::unique_ptr<Preview> PreviewFromFile(
return nullptr; return nullptr;
} }
} else { } else {
object.content = bytes;
if (!LoadFromContent(bytes, &result->instance)) { if (!LoadFromContent(bytes, &result->instance)) {
return nullptr; return nullptr;
} }