diff --git a/Telegram/Resources/default_kotato-settings-custom.json b/Telegram/Resources/default_kotato-settings-custom.json
new file mode 100644
index 000000000..46fa536b5
--- /dev/null
+++ b/Telegram/Resources/default_kotato-settings-custom.json
@@ -0,0 +1,11 @@
+// This is a list of your own settings for Kotatogram Desktop
+// You can see full list of settings in the 'kotato-settings-default.json' file
+
+{
+ // "fonts": {
+ // "main": "Open Sans",
+ // "semibold": "Open Sans Semibold",
+ // "semibold_is_bold": false,
+ // "monospaced": "Consolas"
+ // }
+}
diff --git a/Telegram/Resources/qrc/telegram/telegram.qrc b/Telegram/Resources/qrc/telegram/telegram.qrc
index 87ee77587..25ab0b68a 100644
--- a/Telegram/Resources/qrc/telegram/telegram.qrc
+++ b/Telegram/Resources/qrc/telegram/telegram.qrc
@@ -56,5 +56,6 @@
../../default_shortcuts-custom.json
+ ../../default_kotato-settings-custom.json
diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp
index 74454a300..e3d24bfa5 100644
--- a/Telegram/SourceFiles/core/application.cpp
+++ b/Telegram/SourceFiles/core/application.cpp
@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/sandbox.h"
#include "core/local_url_handlers.h"
#include "core/launcher.h"
+#include "core/kotato_settings.h"
#include "core/core_ui_integration.h"
#include "chat_helpers/emoji_keywords.h"
#include "storage/localstorage.h"
@@ -157,10 +158,12 @@ Application::~Application() {
Global::finish();
ThirdParty::finish();
+ KotatoSettings::Finish();
Instance = nullptr;
}
void Application::run() {
+ KotatoSettings::Start();
if (!cMainFont().isEmpty()) {
style::internal::SetMainFont(cMainFont());
}
diff --git a/Telegram/SourceFiles/core/kotato_settings.cpp b/Telegram/SourceFiles/core/kotato_settings.cpp
new file mode 100644
index 000000000..237cffd7e
--- /dev/null
+++ b/Telegram/SourceFiles/core/kotato_settings.cpp
@@ -0,0 +1,205 @@
+/*
+This file is part of Kotatogram Desktop,
+the unofficial app based on Telegram Desktop.
+
+For license and copyright information please follow this link:
+https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL
+*/
+#include "core/kotato_settings.h"
+
+#include "mainwindow.h"
+#include "mainwidget.h"
+#include "window/window_controller.h"
+#include "core/application.h"
+#include "base/parse_helper.h"
+#include "facades.h"
+
+#include
+#include
+#include
+
+namespace KotatoSettings {
+namespace {
+
+class Manager {
+public:
+ void fill();
+ void clear();
+
+ const QStringList &errors() const;
+
+private:
+ void writeDefaultFile();
+ bool readCustomFile();
+
+ QStringList _errors;
+
+};
+
+QString DefaultFilePath() {
+ return cWorkingDir() + qsl("tdata/kotato-settings-default.json");
+}
+
+QString CustomFilePath() {
+ return cWorkingDir() + qsl("tdata/kotato-settings-custom.json");
+}
+
+bool DefaultFileIsValid() {
+ QFile file(DefaultFilePath());
+ if (!file.open(QIODevice::ReadOnly)) {
+ return false;
+ }
+ auto error = QJsonParseError{ 0, QJsonParseError::NoError };
+ const auto document = QJsonDocument::fromJson(
+ base::parse::stripComments(file.readAll()),
+ &error);
+ file.close();
+
+ if (error.error != QJsonParseError::NoError || !document.isObject()) {
+ return false;
+ }
+ const auto settings = document.object();
+
+ const auto version = settings.constFind(qsl("version"));
+ if (version == settings.constEnd() || (*version).toInt() != AppKotatoVersion) {
+ return false;
+ }
+
+ return true;
+}
+
+void WriteDefaultCustomFile() {
+ const auto path = CustomFilePath();
+ auto input = QFile(":/misc/default_kotato-settings-custom.json");
+ auto output = QFile(path);
+ if (input.open(QIODevice::ReadOnly) && output.open(QIODevice::WriteOnly)) {
+ output.write(input.readAll());
+ }
+}
+
+void Manager::fill() {
+ if (!DefaultFileIsValid()) {
+ writeDefaultFile();
+ }
+ if (!readCustomFile()) {
+ WriteDefaultCustomFile();
+ }
+}
+
+void Manager::clear() {
+ _errors.clear();
+}
+
+const QStringList &Manager::errors() const {
+ return _errors;
+}
+
+bool Manager::readCustomFile() {
+ QFile file(CustomFilePath());
+ if (!file.exists()) {
+ return false;
+ }
+ const auto guard = gsl::finally([&] {
+ if (!_errors.isEmpty()) {
+ _errors.push_front(qsl("While reading file '%1'..."
+ ).arg(file.fileName()));
+ }
+ });
+ if (!file.open(QIODevice::ReadOnly)) {
+ _errors.push_back(qsl("Could not read the file!"));
+ return true;
+ }
+ auto error = QJsonParseError{ 0, QJsonParseError::NoError };
+ const auto document = QJsonDocument::fromJson(
+ base::parse::stripComments(file.readAll()),
+ &error);
+ file.close();
+
+ if (error.error != QJsonParseError::NoError) {
+ _errors.push_back(qsl("Failed to parse! Error: %2"
+ ).arg(error.errorString()));
+ return true;
+ } else if (!document.isObject()) {
+ _errors.push_back(qsl("Failed to parse! Error: object expected"));
+ return true;
+ }
+ const auto settings = document.object();
+
+ if (settings.isEmpty()) {
+ return true;
+ }
+
+ const auto settingsFontsIterator = settings.constFind(qsl("fonts"));
+
+ if (settingsFontsIterator != settings.constEnd() && (*settingsFontsIterator).isObject()) {
+ const auto settingsFonts = (*settingsFontsIterator).toObject();
+
+ const auto settingsFontsMain = settingsFonts.constFind(qsl("main"));
+ if (settingsFontsMain != settingsFonts.constEnd() && (*settingsFontsMain).isString()) {
+ cSetMainFont((*settingsFontsMain).toString());
+ }
+
+ const auto settingsFontsSemibold = settingsFonts.constFind(qsl("semibold"));
+ if (settingsFontsSemibold != settingsFonts.constEnd() && (*settingsFontsSemibold).isString()) {
+ cSetSemiboldFont((*settingsFontsSemibold).toString());
+ }
+
+ const auto settingsFontsSemiboldIsBold = settingsFonts.constFind(qsl("semibold_is_bold"));
+ if (settingsFontsSemiboldIsBold != settingsFonts.constEnd() && (*settingsFontsSemiboldIsBold).isBool()) {
+ cSetSemiboldFontIsBold((*settingsFontsSemiboldIsBold).toBool());
+ }
+
+ const auto settingsFontsMonospace = settingsFonts.constFind(qsl("monospaced"));
+ if (settingsFontsMonospace != settingsFonts.constEnd() && (*settingsFontsMonospace).isString()) {
+ cSetMonospaceFont((*settingsFontsMonospace).toString());
+ }
+ }
+ return true;
+}
+
+void Manager::writeDefaultFile() {
+ auto file = QFile(DefaultFilePath());
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+ const char *defaultHeader = R"HEADER(
+// This is a list of default options for Kotatogram Desktop
+// Please don't modify it, its content is not used in any way
+// You can place your own options in the 'kotato-settings-custom.json' file
+
+)HEADER";
+ file.write(defaultHeader);
+
+ auto settings = QJsonObject();
+ settings.insert(qsl("version"), QString::number(AppKotatoVersion));
+
+ auto settingsFonts = QJsonObject();
+ settingsFonts.insert(qsl("main"), qsl("Open Sans"));
+ settingsFonts.insert(qsl("semibold"), qsl("Open Sans Semibold"));
+ settingsFonts.insert(qsl("semibold_is_bold"), false);
+ settingsFonts.insert(qsl("monospaced"), qsl("Consolas"));
+
+ settings.insert(qsl("fonts"), settingsFonts);
+
+ auto document = QJsonDocument();
+ document.setObject(settings);
+ file.write(document.toJson(QJsonDocument::Indented));
+}
+
+Manager Data;
+
+} // namespace
+
+void Start() {
+ Data.fill();
+}
+
+const QStringList &Errors() {
+ return Data.errors();
+}
+
+void Finish() {
+ Data.clear();
+}
+
+} // namespace KotatoSettings
diff --git a/Telegram/SourceFiles/core/kotato_settings.h b/Telegram/SourceFiles/core/kotato_settings.h
new file mode 100644
index 000000000..84cffc5e2
--- /dev/null
+++ b/Telegram/SourceFiles/core/kotato_settings.h
@@ -0,0 +1,17 @@
+/*
+This file is part of Kotatogram Desktop,
+the unofficial app based on Telegram Desktop.
+
+For license and copyright information please follow this link:
+https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL
+*/
+#pragma once
+
+namespace KotatoSettings {
+
+void Start();
+void Finish();
+
+const QStringList &Errors();
+
+} // namespace KotatoSettings
diff --git a/Telegram/gyp/telegram/sources.txt b/Telegram/gyp/telegram/sources.txt
index 38d9d0e64..143adcca5 100644
--- a/Telegram/gyp/telegram/sources.txt
+++ b/Telegram/gyp/telegram/sources.txt
@@ -157,6 +157,8 @@
<(src_loc)/core/event_filter.h
<(src_loc)/core/file_utilities.cpp
<(src_loc)/core/file_utilities.h
+<(src_loc)/core/kotato_settings.cpp
+<(src_loc)/core/kotato_settings.h
<(src_loc)/core/launcher.cpp
<(src_loc)/core/launcher.h
<(src_loc)/core/local_url_handlers.cpp