1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include <rpl/producer.h> 11 #include "lang_auto.h" 12 #include "base/weak_ptr.h" 13 14 namespace Lang { 15 16 inline constexpr auto kChoosingStickerReplacement = "oo"_cs; 17 18 struct Language { 19 QString id; 20 QString pluralId; 21 QString baseId; 22 QString name; 23 QString nativeName; 24 }; 25 26 inline bool operator==(const Language &a, const Language &b) { 27 return (a.id == b.id) && (a.name == b.name); 28 } 29 30 inline bool operator!=(const Language &a, const Language &b) { 31 return !(a == b); 32 } 33 34 QString DefaultLanguageId(); 35 QString LanguageIdOrDefault(const QString &id); 36 QString CloudLangPackName(); 37 QString CustomLanguageId(); 38 Language DefaultLanguage(); 39 40 class Instance; 41 Instance &GetInstance(); 42 43 enum class Pack { 44 None, 45 Current, 46 Base, 47 }; 48 49 class Instance { 50 struct PrivateTag; 51 52 public: 53 Instance(); 54 Instance(not_null<Instance*> derived, const PrivateTag &); 55 56 void switchToId(const Language &language); 57 void switchToCustomFile(const QString &filePath); 58 59 Instance(const Instance &other) = delete; 60 Instance &operator=(const Instance &other) = delete; 61 Instance(Instance &&other) = default; 62 Instance &operator=(Instance &&other) = default; 63 64 QString systemLangCode() const; 65 QString langPackName() const; 66 QString cloudLangCode(Pack pack) const; 67 QString id() const; 68 rpl::producer<QString> idChanges() const; 69 QString baseId() const; 70 QString name() const; 71 QString nativeName() const; 72 QString id(Pack pack) const; 73 bool isCustom() const; 74 int version(Pack pack) const; 75 76 QByteArray serialize() const; 77 void fillFromSerialized(const QByteArray &data, int dataAppVersion); 78 79 bool supportChoosingStickerReplacement() const; 80 int rightIndexChoosingStickerReplacement(bool named) const; 81 82 void applyDifference( 83 Pack pack, 84 const MTPDlangPackDifference &difference); 85 static std::map<ushort, QString> ParseStrings( 86 const MTPVector<MTPLangPackString> &strings); 87 updated()88 [[nodiscard]] rpl::producer<> updated() const { 89 return _updated.events(); 90 } 91 getValue(ushort key)92 QString getValue(ushort key) const { 93 Expects(key < _values.size()); 94 95 return _values[key]; 96 } 97 QString getNonDefaultValue(const QByteArray &key) const; isNonDefaultPlural(ushort key)98 bool isNonDefaultPlural(ushort key) const { 99 Expects(key + 5 < _nonDefaultSet.size()); 100 101 return _nonDefaultSet[key] 102 || _nonDefaultSet[key + 1] 103 || _nonDefaultSet[key + 2] 104 || _nonDefaultSet[key + 3] 105 || _nonDefaultSet[key + 4] 106 || _nonDefaultSet[key + 5] 107 || (_base && _base->isNonDefaultPlural(key)); 108 } 109 110 private: 111 void setBaseId(const QString &baseId, const QString &pluralId); 112 113 void applyDifferenceToMe(const MTPDlangPackDifference &difference); 114 void applyValue(const QByteArray &key, const QByteArray &value); 115 void resetValue(const QByteArray &key); 116 void reset(const Language &language); 117 void fillFromCustomContent( 118 const QString &absolutePath, 119 const QString &relativePath, 120 const QByteArray &content); 121 bool loadFromCustomFile(const QString &filePath); 122 void loadFromContent(const QByteArray &content); 123 void loadFromCustomContent( 124 const QString &absolutePath, 125 const QString &relativePath, 126 const QByteArray &content); 127 void updatePluralRules(); 128 void updateChoosingStickerReplacement(); 129 130 Instance *_derived = nullptr; 131 132 QString _id, _pluralId; 133 rpl::event_stream<QString> _idChanges; 134 QString _name, _nativeName; 135 QString _customFilePathAbsolute; 136 QString _customFilePathRelative; 137 QByteArray _customFileContent; 138 int _version = 0; 139 rpl::event_stream<> _updated; 140 141 struct { 142 bool support = false; 143 int rightIndex = 0; 144 int rightIndexNamed = 0; 145 } _choosingStickerReplacement; 146 147 mutable QString _systemLanguage; 148 149 std::vector<QString> _values; 150 std::vector<uchar> _nonDefaultSet; 151 std::map<QByteArray, QByteArray> _nonDefaultValues; 152 153 std::unique_ptr<Instance> _base; 154 155 }; 156 157 namespace details { 158 159 QString Current(ushort key); 160 rpl::producer<QString> Value(ushort key); 161 162 } // namespace details 163 } // namespace Lang 164