From bb7018424aa2210dca2806683a074c9267063a18 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 8 Sep 2019 21:00:31 +0300 Subject: [PATCH] Copy adjusted color values to editor. --- .../window/themes/window_theme.cpp | 1 + .../window/themes/window_theme_editor.cpp | 149 +++++++++--------- .../window/themes/window_theme_editor.h | 5 + .../window/themes/window_theme_editor_box.cpp | 72 +++++---- 4 files changed, 124 insertions(+), 103 deletions(-) diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index 6c60f4e76..703db24c3 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -493,6 +493,7 @@ ChatBackground::AdjustableColor::AdjustableColor(style::color data) , original(data->c) { } +// They're duplicated in window_theme_editor_box.cpp:ReplaceAdjustableColors. ChatBackground::ChatBackground() : _adjustableColors({ st::msgServiceBg, st::msgServiceBgSelected, diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor.cpp index 711269516..dbf96e2c9 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor.cpp @@ -148,52 +148,6 @@ bool isValidColorValue(QLatin1String value) { return true; } -QByteArray replaceValueInContent(const QByteArray &content, const QByteArray &name, const QByteArray &value) { - auto validNames = OrderedSet(); - auto start = content.constBegin(), data = start, end = data + content.size(); - auto lastValidValueStart = end, lastValidValueEnd = end; - while (data != end) { - skipWhitespacesAndComments(data, end); - if (data == end) break; - - auto foundName = base::parse::readName(data, end); - skipWhitespacesAndComments(data, end); - if (data == end || *data != ':') { - return "error"; - } - ++data; - skipWhitespacesAndComments(data, end); - auto valueStart = data; - auto value = readValue(data, end); - auto valueEnd = data; - if (value.size() == 0) { - return "error"; - } - auto validValue = validNames.contains(value) || isValidColorValue(value); - if (validValue) { - validNames.insert(foundName); - if (foundName == name) { - lastValidValueStart = valueStart; - lastValidValueEnd = valueEnd; - } - } - skipWhitespacesAndComments(data, end); - if (data == end || *data != ';') { - return "error"; - } - ++data; - } - if (lastValidValueStart != end) { - auto result = QByteArray(); - result.reserve((lastValidValueStart - start) + value.size() + (end - lastValidValueEnd)); - result.append(start, lastValidValueStart - start); - result.append(value); - if (end - lastValidValueEnd > 0) result.append(lastValidValueEnd, end - lastValidValueEnd); - return result; - } - return QByteArray(); -} - [[nodiscard]] QByteArray ColorizeInContent( QByteArray content, const Colorizer &colorizer) { @@ -302,6 +256,79 @@ private: }; +QByteArray ColorHexString(const QColor &color) { + auto result = QByteArray(); + result.reserve(9); + result.append('#'); + const auto addHex = [&](int code) { + if (code >= 0 && code < 10) { + result.append('0' + code); + } else if (code >= 10 && code < 16) { + result.append('a' + (code - 10)); + } + }; + const auto addValue = [&](int code) { + addHex(code / 16); + addHex(code % 16); + }; + addValue(color.red()); + addValue(color.green()); + addValue(color.blue()); + if (color.alpha() != 255) { + addValue(color.alpha()); + } + return result; +} + +QByteArray ReplaceValueInPaletteContent( + const QByteArray &content, + const QByteArray &name, + const QByteArray &value) { + auto validNames = OrderedSet(); + auto start = content.constBegin(), data = start, end = data + content.size(); + auto lastValidValueStart = end, lastValidValueEnd = end; + while (data != end) { + skipWhitespacesAndComments(data, end); + if (data == end) break; + + auto foundName = base::parse::readName(data, end); + skipWhitespacesAndComments(data, end); + if (data == end || *data != ':') { + return "error"; + } + ++data; + skipWhitespacesAndComments(data, end); + auto valueStart = data; + auto value = readValue(data, end); + auto valueEnd = data; + if (value.size() == 0) { + return "error"; + } + auto validValue = validNames.contains(value) || isValidColorValue(value); + if (validValue) { + validNames.insert(foundName); + if (foundName == name) { + lastValidValueStart = valueStart; + lastValidValueEnd = valueEnd; + } + } + skipWhitespacesAndComments(data, end); + if (data == end || *data != ';') { + return "error"; + } + ++data; + } + if (lastValidValueStart != end) { + auto result = QByteArray(); + result.reserve((lastValidValueStart - start) + value.size() + (end - lastValidValueEnd)); + result.append(start, lastValidValueStart - start); + result.append(value); + if (end - lastValidValueEnd > 0) result.append(lastValidValueEnd, end - lastValidValueEnd); + return result; + } + return QByteArray(); +} + [[nodiscard]] QByteArray WriteCloudToText(const Data::CloudTheme &cloud) { auto result = QByteArray(); const auto add = [&](const QByteArray &key, const QString &value) { @@ -543,36 +570,12 @@ bool Editor::Inner::feedExistingRow(const QString &name, QLatin1String value) { return true; } -QString colorString(QColor color) { - auto result = QString(); - result.reserve(9); - result.append('#'); - const auto addHex = [&](int code) { - if (code >= 0 && code < 10) { - result.append('0' + code); - } else if (code >= 10 && code < 16) { - result.append('a' + (code - 10)); - } - }; - const auto addValue = [&](int code) { - addHex(code / 16); - addHex(code % 16); - }; - addValue(color.red()); - addValue(color.green()); - addValue(color.blue()); - if (color.alpha() != 255) { - addValue(color.alpha()); - } - return result; -} - void Editor::Inner::applyEditing(const QString &name, const QString ©Of, QColor value) { auto plainName = name.toLatin1(); - auto plainValue = (copyOf.isEmpty() ? colorString(value) : copyOf).toLatin1(); - auto newContent = replaceValueInContent(_paletteContent, plainName, plainValue); + auto plainValue = copyOf.isEmpty() ? ColorHexString(value) : copyOf.toLatin1(); + auto newContent = ReplaceValueInPaletteContent(_paletteContent, plainName, plainValue); if (newContent == "error") { - LOG(("Theme Error: could not replace '%1: %2' in content").arg(name).arg(copyOf.isEmpty() ? colorString(value) : copyOf)); + LOG(("Theme Error: could not replace '%1: %2' in content").arg(name).arg(copyOf.isEmpty() ? QString::fromLatin1(ColorHexString(value)) : copyOf)); error(); return; } diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor.h b/Telegram/SourceFiles/window/themes/window_theme_editor.h index c0a12506b..b0f6ea58d 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor.h +++ b/Telegram/SourceFiles/window/themes/window_theme_editor.h @@ -32,6 +32,11 @@ struct ParsedTheme { bool tiled = false; }; +[[nodiscard]] QByteArray ColorHexString(const QColor &color); +[[nodiscard]] QByteArray ReplaceValueInPaletteContent( + const QByteArray &content, + const QByteArray &name, + const QByteArray &value); [[nodiscard]] QByteArray WriteCloudToText(const Data::CloudTheme &cloud); [[nodiscard]] Data::CloudTheme ReadCloudFromText(const QByteArray &text); diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp index 0d6b121fb..78facefca 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp @@ -247,6 +247,37 @@ void ImportFromFile( return QString::fromUtf8(string.data(), string.size()); } +// They're duplicated in window_theme.cpp:ChatBackground::ChatBackground. +[[nodiscard]] QByteArray ReplaceAdjustableColors(QByteArray data) { + const auto &themeObject = Background()->themeObject(); + const auto &paper = Background()->paper(); + const auto usingDefaultTheme = themeObject.pathAbsolute.isEmpty(); + const auto usingThemeBackground = usingDefaultTheme + ? Data::IsDefaultWallPaper(paper) + : Data::IsThemeWallPaper(paper); + + if (usingThemeBackground) { + return data; + } + + const auto adjustables = base::flat_map{ + { qba(qstr("msgServiceBg")), st::msgServiceBg }, + { qba(qstr("msgServiceBgSelected")), st::msgServiceBgSelected }, + { qba(qstr("historyScrollBg")), st::historyScrollBg }, + { qba(qstr("historyScrollBgOver")), st::historyScrollBgOver }, + { qba(qstr("historyScrollBarBg")), st::historyScrollBarBg }, + { qba(qstr("historyScrollBarBgOver")), st::historyScrollBarBgOver } + }; + for (const auto &[name, color] : adjustables) { + data = ReplaceValueInPaletteContent( + data, + name, + ColorHexString(color->c)); + } + return data; +} + +// Only is valid for current theme, pass Local::ReadThemeContent() here. [[nodiscard]] ParsedTheme ParseTheme( const Object &theme, bool onlyPalette = false) { @@ -258,6 +289,7 @@ void ImportFromFile( std::move(raw.palette), colorizer); } + raw.palette = ReplaceAdjustableColors(std::move(raw.palette)); return raw; }; @@ -310,29 +342,6 @@ void ImportFromFile( return result(); } -[[nodiscard]] bool CopyColorsToPalette( - const QString &destination, - const Object &theme, - const Data::CloudTheme &cloud) { - auto parsed = ParseTheme(theme, true); - if (parsed.palette.isEmpty()) { - return false; - } - - QFile f(destination); - if (!f.open(QIODevice::WriteOnly)) { - LOG(("Theme Error: could not open file for write '%1'").arg(destination)); - return false; - } - - const auto content = WriteCloudToText(cloud) + parsed.palette; - if (f.write(content) != content.size()) { - LOG(("Theme Error: could not write palette to '%1'").arg(destination)); - return false; - } - return true; -} - QByteArray GenerateDefaultPalette() { auto result = QByteArray(); const auto rows = style::main_palette::data(); @@ -355,8 +364,9 @@ QByteArray GenerateDefaultPalette() { return result; } -bool WriteDefaultPalette( +bool CopyColorsToPalette( const QString &path, + const QByteArray &palette, const Data::CloudTheme &cloud) { QFile f(path); if (!f.open(QIODevice::WriteOnly)) { @@ -364,8 +374,9 @@ bool WriteDefaultPalette( return false; } - const auto content = WriteCloudToText(cloud) + GenerateDefaultPalette(); - if (f.write(content) != content.size()) { + const auto prefix = WriteCloudToText(cloud); + if (f.write(prefix) != prefix.size() + || f.write(palette) != palette.size()) { LOG(("Theme Error: could not write palette to '%1'").arg(path)); return false; } @@ -688,10 +699,11 @@ void StartEditor( const Data::CloudTheme &cloud) { const auto path = EditingPalettePath(); auto object = Local::ReadThemeContent(); - const auto written = object.content.isEmpty() - ? WriteDefaultPalette(path, cloud) - : CopyColorsToPalette(path, object, cloud); - if (!written) { + + const auto palette = object.content.isEmpty() + ? GenerateDefaultPalette() + : ParseTheme(object, true).palette; + if (palette.isEmpty() || !CopyColorsToPalette(path, palette, cloud)) { window->show(Box(tr::lng_theme_editor_error(tr::now))); return; }