/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include #include "lang_auto.h" #include "base/weak_ptr.h" namespace Lang { struct Language { QString id; QString pluralId; QString baseId; QString name; QString nativeName; }; inline bool operator==(const Language &a, const Language &b) { return (a.id == b.id) && (a.name == b.name); } inline bool operator!=(const Language &a, const Language &b) { return !(a == b); } QString DefaultLanguageId(); QString LanguageIdOrDefault(const QString &id); QString CloudLangPackName(); QString CustomLanguageId(); Language DefaultLanguage(); class Instance; Instance &Current(); enum class Pack { None, Current, Base, }; class Instance { struct PrivateTag; public: Instance(); Instance(not_null derived, const PrivateTag &); void switchToId(const Language &language); void switchToCustomFile(const QString &filePath); Instance(const Instance &other) = delete; Instance &operator=(const Instance &other) = delete; Instance(Instance &&other) = default; Instance &operator=(Instance &&other) = default; QString systemLangCode() const; QString langPackName() const; QString cloudLangCode(Pack pack) const; QString id() const; rpl::producer idChanges() const; QString baseId() const; QString name() const; QString nativeName() const; QString id(Pack pack) const; bool isCustom() const; int version(Pack pack) const; QByteArray serialize() const; void fillFromSerialized(const QByteArray &data, int dataAppVersion); void applyDifference( Pack pack, const MTPDlangPackDifference &difference); static std::map ParseStrings( const MTPVector &strings); base::Observable &updated() { return _updated; } QString getValue(ushort key) const { Expects(key < _values.size()); return _values[key]; } QString getNonDefaultValue(const QByteArray &key) const; bool isNonDefaultPlural(ushort key) const { Expects(key + 5 < _nonDefaultSet.size()); return _nonDefaultSet[key] || _nonDefaultSet[key + 1] || _nonDefaultSet[key + 2] || _nonDefaultSet[key + 3] || _nonDefaultSet[key + 4] || _nonDefaultSet[key + 5] || (_base && _base->isNonDefaultPlural(key)); } private: void setBaseId(const QString &baseId, const QString &pluralId); void applyDifferenceToMe(const MTPDlangPackDifference &difference); void applyValue(const QByteArray &key, const QByteArray &value); void resetValue(const QByteArray &key); void reset(const Language &language); void fillFromCustomContent( const QString &absolutePath, const QString &relativePath, const QByteArray &content); bool loadFromCustomFile(const QString &filePath); void loadFromContent(const QByteArray &content); void loadFromCustomContent( const QString &absolutePath, const QString &relativePath, const QByteArray &content); void updatePluralRules(); Instance *_derived = nullptr; QString _id, _pluralId; rpl::event_stream _idChanges; QString _name, _nativeName; QString _customFilePathAbsolute; QString _customFilePathRelative; QByteArray _customFileContent; int _version = 0; base::Observable _updated; mutable QString _systemLanguage; std::vector _values; std::vector _nonDefaultSet; std::map _nonDefaultValues; std::unique_ptr _base; }; namespace details { QString Current(ushort key); rpl::producer Viewer(ushort key); } // namespace details } // namespace Lang